@esfaenza/extensions 15.2.3 → 15.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, NgModule, Injector, Injectable, Inject, Optional } 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, map } from 'rxjs/operators';
7
+ import { Deserialize } from 'cerialize';
3
8
  import swal from 'sweetalert2';
4
9
  import { ToastrService } from 'ngx-toastr';
5
10
  import { of, Subject } from 'rxjs';
6
- import { map } from 'rxjs/operators';
7
- import { Deserialize } from 'cerialize';
8
11
 
9
- /**
10
- * Token che identifica il locale da utilizzare per questa libreria, sono supportati i locali 'it-IT' ed 'en-US'
11
- */
12
- const EXT_LOCALE = new InjectionToken('EXT_LOCALE');
13
- /**
14
- * Token che indica se la libreria deve utilizzare la libreria 'sweetalerts2' (più graficamente piacevolo) o se limitarsi ad usare 'toastr'
15
- */
16
- const EXT_FANCY_ALERTS = new InjectionToken('EXT_FANCY_ALERTS');
17
12
  /**
18
13
  * 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'
19
14
  */
@@ -23,856 +18,301 @@ const APPSEARCH_PREFIX = new InjectionToken('APPSEARCH_PREFIX');
23
18
  */
24
19
  const EXT_ALLOW_UTC = new InjectionToken('EXT_ALLOW_UTC');
25
20
 
26
- // Angular
27
- /**
28
- * Modulo di estensione che non registra nessun servizio di estensione, dovranno essere dichiarati 1 per 1 dall'applicazione che li utilizza
29
- */
30
- class ExtensionsModule {
31
- static forRoot(config) {
32
- return {
33
- ngModule: ExtensionsModule,
34
- providers: [
35
- { provide: EXT_LOCALE, useValue: (config === null || config === void 0 ? void 0 : config.locale) || 'it-IT' },
36
- { provide: EXT_FANCY_ALERTS, useValue: (config === null || config === void 0 ? void 0 : config.fancy_alerts) || true },
37
- { provide: APPSEARCH_PREFIX, useValue: (config === null || config === void 0 ? void 0 : config.appsearch_prefix) || 'Hot' },
38
- { 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 }
39
- ]
40
- };
41
- }
42
- }
43
- ExtensionsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
44
- ExtensionsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule });
45
- ExtensionsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule });
46
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, decorators: [{
47
- type: NgModule
48
- }] });
49
-
50
- // Angular
51
21
  /**
52
- * Service che fornisce funzionalità di alert nei tipi fondamentali: success, info, warning e danger
53
- */
54
- class MessageService {
22
+ * Service che fornisce dei metodi di estensione per la gestione/manipolazione delle date
23
+ */
24
+ class DateService {
55
25
  /**
56
26
  * Costruttore
57
27
  *
58
28
  * @ignore
59
29
  */
60
- constructor(injector, FANCY_ALERTS, LOCALE) {
61
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
62
- this.injector = injector;
63
- this.FANCY_ALERTS = FANCY_ALERTS;
64
- this.LOCALE = LOCALE;
30
+ constructor(locProvider, allowUtc) {
31
+ this.locProvider = locProvider;
32
+ this.allowUtc = allowUtc;
65
33
  /**
66
- * Oggetto statico in supporto alla localizzazione
34
+ * Oggetto statico di localizzazione per i messaggi di questa Service
67
35
  */
68
36
  this.loc = {
69
- 'Confirm': { 'en-US': "Confirm", 'it-IT': "Conferma", },
70
- 'Cancel': { 'en-US': "Cancel", 'it-IT': "Annulla", },
71
- 'Close': { 'en-US': "Close", 'it-IT': "Chiudi", },
72
- 'Error': { 'en-US': "Error", 'it-IT': "Errore", },
73
- 'Info': { 'en-US': "Info", 'it-IT': "Informazione", },
74
- 'Success': { 'en-US': "Success", 'it-IT': "Successo", },
75
- 'Warning': { 'en-US': "Warning", 'it-IT': "Attenzione", }
37
+ "SMALL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY", 'it-IT': "DD/MM/YYYY" },
38
+ "FULL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
39
+ "FULL_DATE_FORMAT_NO_SS": { 'en-US': "MM/DD/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
40
+ "SMALL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY", 'it-IT': "DD/MM/YYYY" },
41
+ "SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR": { 'en-US': "DD/MM/YYYY HH", 'it-IT': "DD/MM/YYYY HH" },
42
+ "SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
43
+ "FULL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
44
+ "FULL_DATE_DISPLAY_FORMAT_NO_SS": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" }
76
45
  };
77
- this.expiredSessionSwal = swal.mixin({
78
- showCancelButton: false,
79
- confirmButtonText: 'Login',
80
- customClass: {
81
- confirmButton: "btn btn-primary",
82
- container: "app-wrap",
83
- },
84
- buttonsStyling: false,
85
- reverseButtons: false,
86
- allowOutsideClick: false,
87
- icon: "warning"
88
- });
89
- this.successSwalWithCancel = swal.mixin({
90
- title: this.loc["Success"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'],
91
- customClass: {
92
- confirmButton: "btn btn-primary",
93
- cancelButton: "btn btn-secondary app-margin-right-10",
94
- container: "app-wrap",
95
- },
96
- buttonsStyling: false,
97
- reverseButtons: true,
98
- showCancelButton: true,
99
- confirmButtonText: this.loc["Confirm"][(_b = this.LOCALE) !== null && _b !== void 0 ? _b : 'it-IT'],
100
- cancelButtonText: this.loc["Cancel"][(_c = this.LOCALE) !== null && _c !== void 0 ? _c : 'it-IT'],
101
- icon: "success"
102
- });
103
- this.warningSwalWithCancel = swal.mixin({
104
- title: this.loc["Warning"][(_d = this.LOCALE) !== null && _d !== void 0 ? _d : 'it-IT'],
105
- customClass: {
106
- confirmButton: "btn btn-primary",
107
- cancelButton: "btn btn-secondary app-margin-right-10",
108
- container: "app-wrap",
109
- },
110
- buttonsStyling: false,
111
- reverseButtons: true,
112
- showCancelButton: true,
113
- confirmButtonText: this.loc["Confirm"][(_e = this.LOCALE) !== null && _e !== void 0 ? _e : 'it-IT'],
114
- cancelButtonText: this.loc["Cancel"][(_f = this.LOCALE) !== null && _f !== void 0 ? _f : 'it-IT'],
115
- icon: "warning"
116
- });
117
- this.warningSwal = swal.mixin({
118
- title: this.loc["Warning"][(_g = this.LOCALE) !== null && _g !== void 0 ? _g : 'it-IT'],
119
- customClass: {
120
- confirmButton: "btn btn-primary",
121
- container: "app-wrap",
122
- },
123
- buttonsStyling: false,
124
- reverseButtons: true,
125
- showCancelButton: false,
126
- confirmButtonText: this.loc["Close"][(_h = this.LOCALE) !== null && _h !== void 0 ? _h : 'it-IT'],
127
- icon: "warning"
128
- });
129
- this.successSwal = swal.mixin({
130
- title: this.loc["Success"][(_j = this.LOCALE) !== null && _j !== void 0 ? _j : 'it-IT'],
131
- customClass: {
132
- confirmButton: "btn btn-primary",
133
- container: "app-wrap",
134
- },
135
- buttonsStyling: false,
136
- reverseButtons: true,
137
- showCancelButton: false,
138
- confirmButtonText: this.loc["Close"][(_k = this.LOCALE) !== null && _k !== void 0 ? _k : 'it-IT'],
139
- icon: "success"
140
- });
141
- this.errorSwal = swal.mixin({
142
- title: this.loc["Error"][(_l = this.LOCALE) !== null && _l !== void 0 ? _l : 'it-IT'],
143
- customClass: {
144
- confirmButton: "btn btn-primary",
145
- container: "app-wrap",
146
- },
147
- buttonsStyling: false,
148
- reverseButtons: true,
149
- showCancelButton: false,
150
- confirmButtonText: this.loc["Close"][(_m = this.LOCALE) !== null && _m !== void 0 ? _m : 'it-IT'],
151
- icon: "error"
152
- });
153
- this.infoSwal = swal.mixin({
154
- title: this.loc["Info"][(_o = this.LOCALE) !== null && _o !== void 0 ? _o : 'it-IT'],
155
- customClass: {
156
- confirmButton: "btn btn-primary",
157
- container: "app-wrap",
158
- },
159
- buttonsStyling: false,
160
- reverseButtons: true,
161
- showCancelButton: false,
162
- confirmButtonText: this.loc["Close"][(_p = this.LOCALE) !== null && _p !== void 0 ? _p : 'it-IT'],
163
- icon: "info"
46
+ /**
47
+ * Oggetto di configurazione per tenere da conto le informazioni sui formati
48
+ */
49
+ this.cfg = {
50
+ fulldate: "",
51
+ fulldateDisplay: "",
52
+ smallDate: "",
53
+ fulldateNoSS: "",
54
+ smallDateWithH: "",
55
+ smallDateWithM: "",
56
+ fulldateDisplayNoSS: ""
57
+ };
58
+ this.init();
59
+ }
60
+ init() {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
63
+ this.cfg.smallDate = this.loc["SMALL_DATE_FORMAT"][LOCALE];
64
+ this.cfg.fulldate = this.loc["FULL_DATE_FORMAT"][LOCALE];
65
+ this.cfg.fulldateNoSS = this.loc["FULL_DATE_FORMAT_NO_SS"][LOCALE];
66
+ this.cfg.fulldateDisplay = this.loc["FULL_DATE_DISPLAY_FORMAT"][LOCALE];
67
+ this.cfg.fulldateDisplayNoSS = this.loc["FULL_DATE_DISPLAY_FORMAT_NO_SS"][LOCALE];
68
+ this.cfg.smallDate = this.loc["SMALL_DATE_DISPLAY_FORMAT"][LOCALE];
69
+ this.cfg.smallDateWithH = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR"][LOCALE];
70
+ this.cfg.smallDateWithM = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE"][LOCALE];
164
71
  });
165
72
  }
166
- get toastr() {
167
- return this.injector.get(ToastrService);
168
- }
169
73
  /**
170
- * Presentazione di un semplice messaggio di successo
74
+ * Aggiusta una data in "istante finale" in base a qual è la parte di data significativa.
171
75
  *
172
- * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
173
- * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
76
+ * Es. Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
174
77
  *
175
- * @param {string} text Testo da mostrare
176
- * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
78
+ * @param {any} date Data qualsiasi (Date, stringa, dayjs...), verrà ricondotta ad un oggetto dayJs
79
+ * @param {'day' | 'hour' | 'minute'} timepart Parte significativa della data
80
+ * @param {boolean} printSeconds Indica se effettuare la stampa dei secondi o no
177
81
  */
178
- simpleSuccess(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
179
- let tos = this.toastrOrSwal(secondaryNotificationType);
180
- if (tos == "swal")
181
- this.successSwal.fire("", text);
182
- else
183
- 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 });
82
+ adjustDateToFinalInstant(date, timepart, printSeconds = true) {
83
+ let mydt = this.getDateConvertion(date);
84
+ if (mydt == null)
85
+ return "FE: Not a Date";
86
+ let isZeroTime = mydt.startOf(timepart).valueOf() === mydt.valueOf();
87
+ if (!isZeroTime) {
88
+ if (timepart == "day" && mydt.subtract(1, "hour").hour() == mydt.hour()) {
89
+ // Se l'ora precedente è lo stesso orario dell'ora attuale l'istante finale dev'essere mandato avanti di 1
90
+ mydt = mydt.add(1, "hour");
91
+ }
92
+ return printSeconds ? mydt.format(this.cfg.fulldateDisplay) : mydt.format(this.cfg.fulldateDisplayNoSS);
93
+ }
94
+ let tmpValue = mydt.subtract(1, timepart);
95
+ let value = "";
96
+ // Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
97
+ if (timepart == 'day')
98
+ value = tmpValue.format(this.cfg.smallDate) + " 24:00" + (printSeconds ? ':00' : '');
99
+ // Istante finale dei minuti: giorno 05/10/1992 04:00:00 --> 05/10/1992 03:60(:00)
100
+ else if (timepart == 'hour')
101
+ value = tmpValue.format(this.cfg.smallDateWithH) + ":60" + (printSeconds ? ':00' : '');
102
+ // Istante finale dei secondi: giorno 05/10/1992 04:10:00 --> 05/10/1992 04:09:60
103
+ else if (timepart == 'minute')
104
+ value = tmpValue.format(this.cfg.smallDateWithM) + ":60";
105
+ return value;
184
106
  }
185
107
  /**
186
- * Presentazione di un semplice messaggio di informazione
108
+ * Funzione che effettua l'ordinamento fra 2 date in base alla direzione specificata
187
109
  *
188
- * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
189
- * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
110
+ * @param {any} a Prima data per il confronto
111
+ * @param {any} b Seconda data per il confronto
112
+ * @param {'asc' | 'desc'} direction Direzione rispetto a cui ordinare le due date
190
113
  *
191
- * @param {string} text Testo da mostrare
192
- * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
114
+ * @returns {number} 0 se le date sono uguali, 1 se la data A deve venire logicamente prima della data B, -1 altrimenti
193
115
  */
194
- simpleInfo(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
195
- let tos = this.toastrOrSwal(secondaryNotificationType);
196
- if (tos == "swal")
197
- this.infoSwal.fire("", text);
198
- else
199
- 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 });
116
+ dateSort(a, b, direction) {
117
+ if (a < b)
118
+ return direction == 'asc' ? 1 : -1;
119
+ else if (a > b)
120
+ return direction == 'asc' ? -1 : 1;
121
+ // con a uguale a b
122
+ return 0;
200
123
  }
201
124
  /**
202
- * Presentazione di un semplice messaggio di errore
125
+ * Effettua il trim dei secondi da una data espressa come stringa
203
126
  *
204
- * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
205
- * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
127
+ * @param {string} value Data espressa come stringa
206
128
  *
207
- * @param {string} text Testo da mostrare
208
- * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
129
+ * @returns {string} Data senza i secondi
209
130
  */
210
- simpleError(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
211
- let tos = this.toastrOrSwal(secondaryNotificationType);
212
- if (tos == "swal")
213
- this.errorSwal.fire("", text);
214
- else
215
- 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 });
131
+ trimSeconds(value) {
132
+ //I numeri mangiati da dayjs spesso vengono ricondotti a date vere. Mi assicuro che se ci sono solo numeri proseguo
133
+ if (!isNaN(value))
134
+ return value;
135
+ //Se non ho qualcosa del tipo XX/YY/ZZZZ aa:bb:cc di sicuro non è una data che mi interessa
136
+ if (!/^\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d$/g.test(value))
137
+ return value;
138
+ //In questo caso mi arrivano valori che devono essere stampati as-is, solo tagliando i secondi
139
+ return "'" + value.substr(0, value.length - 3);
216
140
  }
217
141
  /**
218
- * Presentazione di un semplice messaggio di avviso
142
+ * Data una lista di date Da e una lista di date A restituisce un oggetto rappresentante il range che include tutte le date passate
219
143
  *
220
- * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
221
- * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
144
+ * @param {any[]} fromDates Lista dei Da
145
+ * @param {any[]} toDates Lista dei A
222
146
  *
223
- * @param {string} text Testo da mostrare
224
- * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
225
- */
226
- simpleWarning(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
227
- let tos = this.toastrOrSwal(secondaryNotificationType);
228
- if (tos == "swal")
229
- this.warningSwal.fire("", text);
230
- else
231
- 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 });
232
- }
233
- /**
234
- * Ripulisce tutti i messaggi presenti in un dato momento sullo schermo
147
+ * @returns {{ from: any, to: any }} Range di date Da - A che include tutti i valori di **fromDates** e **toDates**
235
148
  */
236
- clearMessages() {
237
- this.toastr.clear();
238
- swal.close();
149
+ getMinMaxDatesRange(fromDates, toDates) {
150
+ let datesFroms = [];
151
+ let datesTo = [];
152
+ for (let i = 0; i < fromDates.length; i++) {
153
+ let d = fromDates[i];
154
+ var convertion = this.getDateConvertion(d);
155
+ if (convertion)
156
+ datesFroms.push(convertion);
157
+ }
158
+ for (let i = 0; i < toDates.length; i++) {
159
+ let d = toDates[i];
160
+ var convertion = this.getDateConvertion(d);
161
+ if (convertion)
162
+ datesTo.push(convertion);
163
+ }
164
+ return { from: dayjs.min(datesFroms), to: dayjs.max(datesTo) };
239
165
  }
240
166
  /**
241
- * Mostra un messaggio di avviso con richiesta di conferma
167
+ * Ottiene la conversione di una data in qualsiasi formato al formato standard DayJs
242
168
  *
243
- * @param {string} title Titolo del messaggio
244
- * @param {string} text Contenuto del messaggio
169
+ * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
170
+ * @param {boolean} useUtc Indica se usare l'estensione utc di Dayjs per parsare la data o no
245
171
  *
246
- * @returns {Promise} Restituisce una Promise col risultato scelto dall'utente (conferma o no)
172
+ * @returns {any} Data in modalità DayJs
247
173
  */
248
- promiseWarningWithChoice(title, text) {
249
- return this.warningSwalWithCancel.fire(title, text);
174
+ getDateConvertion(date, useUtc = false) {
175
+ if (!date)
176
+ return null;
177
+ if (this.isDayJs(date))
178
+ return date;
179
+ if (this.isJsDate(date))
180
+ return useUtc ? dayjs.utc(date) : dayjs(date);
181
+ // Se non c'è la proprietà length vuol dire che non è una stringa e a questo punto non ho idea di che minchia sia
182
+ let length = date.length;
183
+ if (!length)
184
+ return null;
185
+ if (useUtc && !this.allowUtc)
186
+ throw "@esfaenza/extensions: Richiesta data UTC ma da configurazione la libreria non lo supporta";
187
+ // Per risparmiare chiamate a tentoni, in base alla lunghezza della stringa chiamo direttamente il metodo giusto,
188
+ // controllando poi che mi generi una data come me la aspetto io
189
+ let tryThis = null;
190
+ let toCall = useUtc ? dayjs.utc : dayjs;
191
+ // 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.
192
+ // Per il resto mi baso sulla lunghezza della stringa
193
+ if (date.includes("T"))
194
+ tryThis = toCall(date);
195
+ else if (length == this.cfg.fulldate.length)
196
+ tryThis = toCall(date, this.cfg.fulldate);
197
+ else if (length == this.cfg.smallDate.length)
198
+ tryThis = toCall(date, this.cfg.smallDate);
199
+ else if (length == this.cfg.fulldateNoSS.length)
200
+ tryThis = toCall(date, this.cfg.fulldateNoSS);
201
+ if (tryThis && tryThis.isValid && tryThis.isValid())
202
+ return tryThis;
203
+ // Se niente funziona, null.
204
+ // Ricondurre l'Input ad una data non è possibile.
205
+ return null;
250
206
  }
251
207
  /**
252
- * In base alla configurazione attuale e all'eventuale override per la chiamata del caso indica se bisogna utilizzare toastr o sweetalert
208
+ * Helper che restituisce **true** qualora l'oggetto passato fosse una data vera e propria, **false** altrimenti
253
209
  *
254
- * @param {"toastr" | "swal" | null} providerOverride Override alla modalità configurata
210
+ * @param {any} check Oggetto da controllare
255
211
  *
256
- * @returns {"toastr" | "swal"} Indicazione su che provider di messaggi di avviso debba essere utilizzato
212
+ * @returns {boolean} Indicazione se l'oggetto è un vero Date di Javascript o no
257
213
  */
258
- toastrOrSwal(providerOverride) {
259
- if (providerOverride != null)
260
- return providerOverride;
261
- return this.FANCY_ALERTS == null ? "swal" : this.FANCY_ALERTS ? "swal" : "toastr";
214
+ isJsDate(check) {
215
+ return check && Object.prototype.toString.call(check) === "[object Date]" && !isNaN(check);
262
216
  }
263
217
  /**
264
- * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
265
- *
266
- * @param {string} title Titolo del messaggio
267
- * @param {string} text Contenuto del messaggio
268
- * @param {Function} onsuccess Callback da chimare su conferma
269
- * @param {Function} onerror Callback da chimare su errori
270
- */
271
- simpleWarningWithChoice(title, text, onsuccess = null, onerror = null) {
272
- this.warningSwalWithCancel.fire(title, text).then((result) => {
273
- if (result.value && onsuccess)
274
- onsuccess();
275
- else if (onerror)
276
- onerror();
277
- });
278
- }
279
- /**
280
- * Mostra un messaggio di success con richiesta di conferma e gestisce il risultato chiamato i callback **onconfirm** o **onabort**
281
- *
282
- * @param {string} title Titolo del messaggio
283
- * @param {string} text Contenuto del messaggio
284
- * @param {Function} onconfirm Callback da chimare su conferma
285
- * @param {Function} onabort Callback da chimare su annullamento
286
- * @param {string} confirmtext Testo del pulsante di azione
287
- * @param {string} aborttext Testo del pulsante di annullamento
288
- */
289
- simpleSuccessWithChoice(title, text, onconfirm = null, onabort = null, confirmtext = "", aborttext = '') {
290
- var configuration = {
291
- title: title,
292
- html: text
293
- };
294
- if (confirmtext)
295
- configuration["confirmButtonText"] = confirmtext;
296
- if (aborttext)
297
- configuration["cancelButtonText"] = aborttext;
298
- this.successSwalWithCancel.fire(configuration).then((result) => {
299
- if (result.value && onconfirm)
300
- onconfirm();
301
- else if (onabort)
302
- onabort();
303
- });
304
- }
305
- /**
306
- * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
307
- *
308
- * @param {string} title Titolo del messaggio
309
- * @param {string} text Contenuto del messaggio
310
- */
311
- observableSimpleWarningWithChoice(title, text) {
312
- return of(this.warningSwalWithCancel.fire(title, text)).pipe(map(t => !!t.value));
313
- }
314
- /**
315
- * Mostra un messaggio di avviso che la sessione corrente è scaduta e propone all'utente di navigare al login. Qualora l'utente decidesse di farlo
316
- * verrà chiamata la funzione di callback **onnavigate
317
- *
318
- * @param {string} title Titolo del messaggio
319
- * @param {string} text Contenuto del messaggio
320
- * @param {Function} onnavigate Callback da chimare su navigazione in corso
321
- */
322
- expiredSessionMessage(title, text, onnavigate = null) {
323
- this.expiredSessionSwal.fire(title, text).then((result) => {
324
- if (result.value && onnavigate)
325
- onnavigate();
326
- });
327
- }
328
- /**
329
- * Metodo helper per gestire in maniera standardizzata una risposta di tipo **CallResult**
218
+ * Helper che restituisce **true** qualora l'oggetto passato fosse un DayJs vero e proprio, **false** altrimenti
330
219
  *
331
- * @param {CallResult} response Risposta ricevuta dal server
332
- * @param {string} successMsg Messaggio da visualizzare in caso di successo
333
- * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
334
- * @param {Function} postSuccess Callback da chimare in caso di successo
335
- * @param {Function} postFailure Callback da chimare in caso di fallimento
220
+ * @param {any} check Oggetto da controllare
221
+ * @returns {boolean} Indicazione se l'oggetto è un vero DayJs o no
336
222
  */
337
- manageCallResultResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
338
- if (response.success) {
339
- if (response.haswarning)
340
- this.simpleWarning(response.warning);
341
- else if (successMsg)
342
- this.simpleSuccess(successMsg);
343
- if (postSuccess)
344
- postSuccess();
345
- }
346
- else {
347
- this.simpleError((errorMsg ? errorMsg + ": " : "") + response.haserror ? response.error : '[NO ERR.]');
348
- if (postFailure)
349
- postFailure();
350
- }
223
+ isDayJs(check) {
224
+ // Non uso instanceof perché sarebbe estremamente più lento
225
+ // Non uso nemmeno isDayjs() della libreria Dayjs dato che ha lo stesso problema: https://github.com/iamkun/dayjs/blob/06f88f425828b1ce96b737332d25145a95a4ee9d/src/index.js#L9
226
+ return check.$D !== undefined && check.$M !== undefined && check.$y !== undefined;
351
227
  }
352
228
  /**
353
- * Metodo helper per gestire in maniera standardizzata una risposta di tipo **string**, considerando che:
354
- *
355
- * Stringa vuota --> Tutto bene
356
- *
357
- * Stringa piena --> Questo è il messaggio d'errore per cui la chiamata è fallita
229
+ * Ottiene la formattazione di una data in base alla versione richiesta "small" o "long" e a se stampare o meno i secondi
358
230
  *
359
- * @param {string} response Risposta ricevuta dal server
360
- * @param {string} successMsg Messaggio da visualizzare in caso di successo
361
- * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
362
- * @param {Function} postSuccess Callback da chimare in caso di successo
363
- * @param {Function} postFailure Callback da chimare in caso di fallimento
364
- */
365
- manageStringResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
366
- if (!response) {
367
- if (successMsg)
368
- this.simpleSuccess(successMsg);
369
- if (postSuccess)
370
- postSuccess();
371
- }
372
- else {
373
- if (errorMsg)
374
- this.simpleError(errorMsg + ": " + response);
375
- if (postFailure)
376
- postFailure();
377
- }
378
- }
379
- /**
380
- * Metodo helper per gestire in maniera standardizzata una risposta di tipo **boolean**
231
+ * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
232
+ * @param {boolean} small Indica se formattarla con un formato breve (se **true**) o un formato più lungo (se **false**)
381
233
  *
382
- * @param {string} response Risposta ricevuta dal server
383
- * @param {string} successMsg Messaggio da visualizzare in caso di successo
384
- * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
385
- * @param {Function} postSuccess Callback da chimare in caso di successo
386
- * @param {Function} postFailure Callback da chimare in caso di fallimento
234
+ * @returns {string} Data formattata nel formato richiesto
387
235
  */
388
- manageStringResponseBool(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
389
- if (response) {
390
- if (successMsg)
391
- this.simpleSuccess(successMsg);
392
- if (postSuccess)
393
- postSuccess();
394
- }
395
- else {
396
- if (errorMsg)
397
- this.simpleError(errorMsg);
398
- if (postFailure)
399
- postFailure();
400
- }
236
+ getFormatted(date, small, seconds) {
237
+ var date = this.getDateConvertion(date);
238
+ if (!date)
239
+ return null;
240
+ return date.format(small ? this.cfg.smallDate : seconds ? this.cfg.fulldateDisplay : this.cfg.fulldateDisplayNoSS);
401
241
  }
402
242
  }
403
- MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, deps: [{ token: Injector }, { token: EXT_FANCY_ALERTS, optional: true }, { token: EXT_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
404
- MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService });
405
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, decorators: [{
406
- type: Injectable
243
+ 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 });
244
+ DateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, providedIn: "root" });
245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, decorators: [{
246
+ type: Injectable,
247
+ args: [{ providedIn: "root" }]
407
248
  }], ctorParameters: function () {
408
- return [{ type: i0.Injector, decorators: [{
409
- type: Inject,
410
- args: [Injector]
411
- }] }, { type: undefined, decorators: [{
249
+ return [{ type: i1.BaseLocalization, decorators: [{
412
250
  type: Optional
413
- }, {
414
- type: Inject,
415
- args: [EXT_FANCY_ALERTS]
416
251
  }] }, { type: undefined, decorators: [{
417
252
  type: Optional
418
253
  }, {
419
254
  type: Inject,
420
- args: [EXT_LOCALE]
255
+ args: [EXT_ALLOW_UTC]
421
256
  }] }];
422
257
  } });
423
258
 
424
259
  // Angular
425
260
  /**
426
- * Service che fornisce un accesso base in lettura/scrittura sulla clipboard
261
+ * 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
427
262
  */
428
- class ClipboardService {
263
+ class LocDatePipe {
429
264
  /**
430
- * Costruttore
431
- *
432
265
  * @ignore
433
266
  */
434
- constructor(msgService, LOCALE) {
435
- this.msgService = msgService;
436
- this.LOCALE = LOCALE;
437
- /**
438
- * Oggetto statico di localizzazione per i messaggi di questa Service
439
- */
440
- this.loc = {
441
- "Unfortunately Firefox doesn't yet support direct Clipboard access if not via extensions, Please use Chrome to do this operation": {
442
- 'en-US': "Unfortunately Firefox doesn't yet support direct Clipboard access if not via extensions, Please use Chrome to do this operation",
443
- 'it-IT': "Mi dispiace ma Firefox non supporta l'accesso diretto alla Clipboard, se non attraverso le estensioni. Si prega di usare Chrome"
444
- },
445
- "Generic error during 'copy' command execution": {
446
- 'en-US': "Generic error during 'copy' command execution",
447
- 'it-IT': "Errore generico durante l'esecuzione del comando 'copy'"
448
- },
449
- "Error during Clipboard content read operation": {
450
- 'en-US': "Error during Clipboard content read operation",
451
- 'it-IT': "Errore nella lettura del contenuto della Clipboard"
452
- },
453
- "Error during Clipboard content copy operation": {
454
- 'en-US': "Error during Clipboard content copy operation",
455
- 'it-IT': "Errore nella scrittura del contenuto nella Clipboard"
456
- },
457
- "Please insert your clipboard content": {
458
- 'en-US': "Please insert your clipboard content",
459
- 'it-IT': "Si prega di incollare il contenuto della Clipboard"
460
- },
461
- "User input required": {
462
- 'en-US': "User input required",
463
- 'it-IT': "Richiesto Input utente"
464
- },
465
- "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": {
466
- '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",
467
- '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"
468
- },
469
- "Confirm": {
470
- 'en-US': "Confirm",
471
- 'it-IT': "Conferma"
472
- },
473
- "Cancel": {
474
- 'en-US': "Cancel",
475
- 'it-IT': "Annulla"
476
- },
477
- };
478
- }
479
- /**
480
- * Prende il valore della clipboard.
481
- * Si può specificare se ci si aspetta una lista o una matrice di valori in modo da ricevere già un risultato utilizzabile
482
- *
483
- * @param {'array' | 'matrix'} style Stile dell'output desiderato, se array o matrice
484
- * @param {Function} valueFoundCallback Callback che questa funzione chiamerà una volta ottenuto i valori richiesti dalla clipboard
485
- */
486
- getClipboard(style, valueFoundCallback) {
487
- var _a, _b, _c, _d;
488
- if (navigator.userAgent.indexOf("Firefox") != -1) {
489
- swal.fire({
490
- title: this.loc["User input required"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'],
491
- 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"][(_b = this.LOCALE) !== null && _b !== void 0 ? _b : 'it-IT'],
492
- input: 'textarea',
493
- icon: "warning",
494
- confirmButtonText: this.loc["Confirm"][(_c = this.LOCALE) !== null && _c !== void 0 ? _c : 'it-IT'],
495
- cancelButtonText: this.loc["Cancel"][(_d = this.LOCALE) !== null && _d !== void 0 ? _d : 'it-IT'],
496
- showCancelButton: true,
497
- customClass: {
498
- confirmButton: "btn btn-primary",
499
- cancelButton: "btn btn-secondary app-margin-right-15",
500
- container: "app-wrap",
501
- },
502
- reverseButtons: true,
503
- allowOutsideClick: false,
504
- inputValidator: (value) => {
505
- var _a;
506
- if (!value)
507
- return this.loc["Please insert your clipboard content"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'];
508
- }
509
- }).then(t => {
510
- if (t.isConfirmed) {
511
- console.log("[@esfaenza/extensions] Retrieving input data from user input");
512
- this.doClipboardDataGet(t.value, style, valueFoundCallback);
513
- }
514
- });
515
- return;
516
- }
517
- if (window.clipboardData) {
518
- console.log("[@esfaenza/extensions] Found clipboardData");
519
- let data = window.clipboardData.getData("Text");
520
- this.doClipboardDataGet(data, style, valueFoundCallback);
521
- }
522
- else if (window.navigator.clipboard) {
523
- console.log("[@esfaenza/extensions] Found navigator clipboard");
524
- window.navigator.permissions.query({ name: 'clipboard-read' }).then(result => {
525
- if (!(result.state === 'granted' || result.state === 'prompt')) {
526
- console.error("[@esfaenza/extensions] Clipboard permission not granted");
527
- if (valueFoundCallback)
528
- valueFoundCallback([]);
529
- return;
530
- }
531
- console.log("[@esfaenza/extensions] Clipboard permission granted, retrieving values");
532
- window.navigator.clipboard.readText()
533
- .then((t) => this.doClipboardDataGet(t, style, valueFoundCallback))
534
- .catch((err) => { var _a; return this.msgService.simpleError(this.loc["Error during Clipboard content read operation"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'] + ": " + err); });
535
- });
536
- }
537
- }
538
- /** @ignore */
539
- doClipboardDataGet(clipboardText, style, valueFoundCallback) {
540
- console.log("[@esfaenza/extensions] Retrieved clipboard values: " + clipboardText);
541
- let value = style == "array" ? this.getClipboardLines(clipboardText) :
542
- style == "matrix" ? this.getClipboardMatrix(clipboardText) : [];
543
- console.log(`[@esfaenza/extensions] Adapted for ${style}: ${JSON.stringify(value)}`);
544
- if (valueFoundCallback)
545
- valueFoundCallback(value);
267
+ constructor(dts) {
268
+ this.dts = dts;
546
269
  }
547
270
  /**
548
- * Ottiene il contenuto della clipboard diviso per righe (separate da newline)
271
+ * Trasformazione della data in input in base al formato richiesto
549
272
  *
550
- * @param {string} data contenuto letto dalla clipboard
273
+ * @param {any} value Valore da ricondurre ad una data e formattare
274
+ * @param {string} format Formato in output della data da visualizzare
551
275
  *
552
- * @returns {string[]} Array contenente il testo preso dalla clipboard diviso per riga
276
+ * @returns {string} Data formattata in base al formato
553
277
  */
554
- getClipboardLines(data) {
555
- let trimmedData = data.trim();
556
- if (!trimmedData.includes("\r\n") && trimmedData.includes("\n"))
557
- return trimmedData.split("\n");
558
- return trimmedData.split("\r\n");
559
- }
560
- /**
561
- * Ottiene il contenuto della clipboard diviso per righe (separate da newline) e colonne (separate da tab)
562
- *
563
- * @param {string} data contenuto letto dalla clipboard
564
- *
565
- * @returns {string[][]} Matrice contenente il testo preso dalla clipboard diviso per riga e colonna
566
- */
567
- getClipboardMatrix(data) {
568
- var ret = [];
569
- var rows = !data.includes("\r\n") && data.includes("\n") ? data.split("\n") : data.split("\r\n");
570
- // A quanto pare ogni valore è separato da un \t... spero che sia uno standard di quando si copia da excel altrimenti ciao
571
- for (let i = 0; i < rows.length; i++)
572
- ret.push(rows[i].split('\t').map(t => t.trim()));
573
- return ret;
574
- }
575
- /**
576
- * Metodo che copia un testo all'interno della clipboard
577
- *
578
- * @param {string} text Testo da inserire nella clipboard
579
- */
580
- copyTextToClipboard(text) {
581
- var _a, _b;
582
- var textArea = document.createElement("textarea");
583
- //
584
- // *** This styling is an extra step which is likely not required. ***
585
- //
586
- // Why is it here? To ensure:
587
- // 1. the element is able to have focus and selection.
588
- // 2. if element was to flash render it has minimal visual impact.
589
- // 3. less flakyness with selection and copying which **might** occur if
590
- // the textarea element is not visible.
591
- //
592
- // The likelihood is the element won't even render, not even a flash,
593
- // so some of these are just precautions. However in IE the element
594
- // is visible whilst the popup box asking the user for permission for
595
- // the web page to copy to the clipboard.
596
- //
597
- // Place in top-left corner of screen regardless of scroll position.
598
- textArea.style.position = "fixed";
599
- textArea.style.top = "0";
600
- textArea.style.left = "0";
601
- // Ensure it has a small width and height. Setting to 1px / 1em
602
- // doesn't work as this gives a negative w/h on some browsers.
603
- textArea.style.width = "2em";
604
- textArea.style.height = "2em";
605
- // We don't need padding, reducing the size if it does flash render.
606
- textArea.style.padding = "0";
607
- // Clean up any borders.
608
- textArea.style.border = "none";
609
- textArea.style.outline = "none";
610
- textArea.style.boxShadow = "none";
611
- // Avoid flash of white box if rendered for any reason.
612
- textArea.style.background = "transparent";
613
- textArea.value = text;
614
- document.body.appendChild(textArea);
615
- textArea.focus();
616
- textArea.select();
617
- try {
618
- var successful = document.execCommand("copy");
619
- if (!successful)
620
- this.msgService.simpleError(this.loc["Generic error during 'copy' command execution"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT']);
621
- }
622
- catch (err) {
623
- this.msgService.simpleError(this.loc["Error during Clipboard content copy operation"][(_b = this.LOCALE) !== null && _b !== void 0 ? _b : 'it-IT'] + ": " + err);
624
- }
625
- document.body.removeChild(textArea);
278
+ transform(value, format = "DD/MM/YYYY") {
279
+ if (value == null || value === "")
280
+ return null;
281
+ var detatchedValue = JSON.parse(JSON.stringify(value));
282
+ var dt = this.dts.getDateConvertion(detatchedValue);
283
+ return dt.format(format);
626
284
  }
627
285
  }
628
- ClipboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, deps: [{ token: MessageService }, { token: EXT_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
629
- ClipboardServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService });
630
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, decorators: [{
631
- type: Injectable
632
- }], ctorParameters: function () {
633
- return [{ type: MessageService }, { type: undefined, decorators: [{
634
- type: Optional
635
- }, {
636
- type: Inject,
637
- args: [EXT_LOCALE]
638
- }] }];
639
- } });
286
+ LocDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LocDatePipe, deps: [{ token: DateService }], target: i0.ɵɵFactoryTarget.Pipe });
287
+ LocDatePipepipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: LocDatePipe, name: "loc_date" });
288
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LocDatePipe, decorators: [{
289
+ type: Pipe,
290
+ args: [{ name: "loc_date", pure: true }]
291
+ }], ctorParameters: function () { return [{ type: DateService }]; } });
640
292
 
641
293
  // Angular
642
- /**
643
- * Service che fornisce dei metodi di estensione per la gestione/manipolazione delle date
644
- */
645
- class DateService {
646
- /**
647
- * Costruttore
648
- *
649
- * @ignore
650
- */
651
- constructor(LOCALE, allowUtc) {
652
- var _a, _b, _c, _d, _e, _f, _g, _h;
653
- this.LOCALE = LOCALE;
654
- this.allowUtc = allowUtc;
655
- /**
656
- * Oggetto statico di localizzazione per i messaggi di questa Service
657
- */
658
- this.loc = {
659
- "SMALL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY", 'it-IT': "DD/MM/YYYY" },
660
- "FULL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
661
- "FULL_DATE_FORMAT_NO_SS": { 'en-US': "MM/DD/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
662
- "SMALL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY", 'it-IT': "DD/MM/YYYY" },
663
- "SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR": { 'en-US': "DD/MM/YYYY HH", 'it-IT': "DD/MM/YYYY HH" },
664
- "SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
665
- "FULL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
666
- "FULL_DATE_DISPLAY_FORMAT_NO_SS": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" }
667
- };
668
- /**
669
- * Oggetto di configurazione per tenere da conto le informazioni sui formati
670
- */
671
- this.cfg = {
672
- fulldate: "",
673
- fulldateDisplay: "",
674
- smallDate: "",
675
- fulldateNoSS: "",
676
- smallDateWithH: "",
677
- smallDateWithM: "",
678
- fulldateDisplayNoSS: ""
294
+ class ExtensionsModule {
295
+ static forRoot(config) {
296
+ return {
297
+ ngModule: ExtensionsModule,
298
+ providers: [
299
+ { provide: APPSEARCH_PREFIX, useValue: (config === null || config === void 0 ? void 0 : config.appsearch_prefix) || 'Hot' },
300
+ { 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 }
301
+ ]
679
302
  };
680
- this.cfg.smallDate = this.loc["SMALL_DATE_FORMAT"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'];
681
- this.cfg.fulldate = this.loc["FULL_DATE_FORMAT"][(_b = this.LOCALE) !== null && _b !== void 0 ? _b : 'it-IT'];
682
- this.cfg.fulldateNoSS = this.loc["FULL_DATE_FORMAT_NO_SS"][(_c = this.LOCALE) !== null && _c !== void 0 ? _c : 'it-IT'];
683
- this.cfg.fulldateDisplay = this.loc["FULL_DATE_DISPLAY_FORMAT"][(_d = this.LOCALE) !== null && _d !== void 0 ? _d : 'it-IT'];
684
- this.cfg.fulldateDisplayNoSS = this.loc["FULL_DATE_DISPLAY_FORMAT_NO_SS"][(_e = this.LOCALE) !== null && _e !== void 0 ? _e : 'it-IT'];
685
- this.cfg.smallDate = this.loc["SMALL_DATE_DISPLAY_FORMAT"][(_f = this.LOCALE) !== null && _f !== void 0 ? _f : 'it-IT'];
686
- this.cfg.smallDateWithH = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR"][(_g = this.LOCALE) !== null && _g !== void 0 ? _g : 'it-IT'];
687
- this.cfg.smallDateWithM = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE"][(_h = this.LOCALE) !== null && _h !== void 0 ? _h : 'it-IT'];
688
- }
689
- /**
690
- * Aggiusta una data in "istante finale" in base a qual è la parte di data significativa.
691
- *
692
- * Es. Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
693
- *
694
- * @param {any} date Data qualsiasi (Date, stringa, dayjs...), verrà ricondotta ad un oggetto dayJs
695
- * @param {'day' | 'hour' | 'minute'} timepart Parte significativa della data
696
- * @param {boolean} printSeconds Indica se effettuare la stampa dei secondi o no
697
- */
698
- adjustDateToFinalInstant(date, timepart, printSeconds = true) {
699
- let mydt = this.getDateConvertion(date);
700
- if (mydt == null)
701
- return "FE: Not a Date";
702
- let isZeroTime = mydt.startOf(timepart).valueOf() === mydt.valueOf();
703
- if (!isZeroTime) {
704
- if (timepart == "day" && mydt.subtract(1, "hour").hour() == mydt.hour()) {
705
- // Se l'ora precedente è lo stesso orario dell'ora attuale l'istante finale dev'essere mandato avanti di 1
706
- mydt = mydt.add(1, "hour");
707
- }
708
- return printSeconds ? mydt.format(this.cfg.fulldateDisplay) : mydt.format(this.cfg.fulldateDisplayNoSS);
709
- }
710
- let tmpValue = mydt.subtract(1, timepart);
711
- let value = "";
712
- // Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
713
- if (timepart == 'day')
714
- value = tmpValue.format(this.cfg.smallDate) + " 24:00" + (printSeconds ? ':00' : '');
715
- // Istante finale dei minuti: giorno 05/10/1992 04:00:00 --> 05/10/1992 03:60(:00)
716
- else if (timepart == 'hour')
717
- value = tmpValue.format(this.cfg.smallDateWithH) + ":60" + (printSeconds ? ':00' : '');
718
- // Istante finale dei secondi: giorno 05/10/1992 04:10:00 --> 05/10/1992 04:09:60
719
- else if (timepart == 'minute')
720
- value = tmpValue.format(this.cfg.smallDateWithM) + ":60";
721
- return value;
722
- }
723
- /**
724
- * Funzione che effettua l'ordinamento fra 2 date in base alla direzione specificata
725
- *
726
- * @param {any} a Prima data per il confronto
727
- * @param {any} b Seconda data per il confronto
728
- * @param {'asc' | 'desc'} direction Direzione rispetto a cui ordinare le due date
729
- *
730
- * @returns {number} 0 se le date sono uguali, 1 se la data A deve venire logicamente prima della data B, -1 altrimenti
731
- */
732
- dateSort(a, b, direction) {
733
- if (a < b)
734
- return direction == 'asc' ? 1 : -1;
735
- else if (a > b)
736
- return direction == 'asc' ? -1 : 1;
737
- // con a uguale a b
738
- return 0;
739
- }
740
- /**
741
- * Effettua il trim dei secondi da una data espressa come stringa
742
- *
743
- * @param {string} value Data espressa come stringa
744
- *
745
- * @returns {string} Data senza i secondi
746
- */
747
- trimSeconds(value) {
748
- //I numeri mangiati da dayjs spesso vengono ricondotti a date vere. Mi assicuro che se ci sono solo numeri proseguo
749
- if (!isNaN(value))
750
- return value;
751
- //Se non ho qualcosa del tipo XX/YY/ZZZZ aa:bb:cc di sicuro non è una data che mi interessa
752
- if (!/^\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d$/g.test(value))
753
- return value;
754
- //In questo caso mi arrivano valori che devono essere stampati as-is, solo tagliando i secondi
755
- return "'" + value.substr(0, value.length - 3);
756
- }
757
- /**
758
- * Data una lista di date Da e una lista di date A restituisce un oggetto rappresentante il range che include tutte le date passate
759
- *
760
- * @param {any[]} fromDates Lista dei Da
761
- * @param {any[]} toDates Lista dei A
762
- *
763
- * @returns {{ from: any, to: any }} Range di date Da - A che include tutti i valori di **fromDates** e **toDates**
764
- */
765
- getMinMaxDatesRange(fromDates, toDates) {
766
- let datesFroms = [];
767
- let datesTo = [];
768
- for (let i = 0; i < fromDates.length; i++) {
769
- let d = fromDates[i];
770
- var convertion = this.getDateConvertion(d);
771
- if (convertion)
772
- datesFroms.push(convertion);
773
- }
774
- for (let i = 0; i < toDates.length; i++) {
775
- let d = toDates[i];
776
- var convertion = this.getDateConvertion(d);
777
- if (convertion)
778
- datesTo.push(convertion);
779
- }
780
- return { from: dayjs.min(datesFroms), to: dayjs.max(datesTo) };
781
- }
782
- /**
783
- * Ottiene la conversione di una data in qualsiasi formato al formato standard DayJs
784
- *
785
- * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
786
- * @param {boolean} useUtc Indica se usare l'estensione utc di Dayjs per parsare la data o no
787
- *
788
- * @returns {any} Data in modalità DayJs
789
- */
790
- getDateConvertion(date, useUtc = false) {
791
- if (!date)
792
- return null;
793
- if (this.isDayJs(date))
794
- return date;
795
- if (this.isJsDate(date))
796
- return useUtc ? dayjs.utc(date) : dayjs(date);
797
- // Se non c'è la proprietà length vuol dire che non è una stringa e a questo punto non ho idea di che minchia sia
798
- let length = date.length;
799
- if (!length)
800
- return null;
801
- if (useUtc && !this.allowUtc)
802
- throw "@esfaenza/extensions: Richiesta data UTC ma da configurazione la libreria non lo supporta";
803
- // Per risparmiare chiamate a tentoni, in base alla lunghezza della stringa chiamo direttamente il metodo giusto,
804
- // controllando poi che mi generi una data come me la aspetto io
805
- let tryThis = null;
806
- let toCall = useUtc ? dayjs.utc : dayjs;
807
- // 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.
808
- // Per il resto mi baso sulla lunghezza della stringa
809
- if (date.includes("T"))
810
- tryThis = toCall(date);
811
- else if (length == this.cfg.fulldate.length)
812
- tryThis = toCall(date, this.cfg.fulldate);
813
- else if (length == this.cfg.smallDate.length)
814
- tryThis = toCall(date, this.cfg.smallDate);
815
- else if (length == this.cfg.fulldateNoSS.length)
816
- tryThis = toCall(date, this.cfg.fulldateNoSS);
817
- if (tryThis && tryThis.isValid && tryThis.isValid())
818
- return tryThis;
819
- // Se niente funziona, null.
820
- // Ricondurre l'Input ad una data non è possibile.
821
- return null;
822
- }
823
- /**
824
- * Helper che restituisce **true** qualora l'oggetto passato fosse una data vera e propria, **false** altrimenti
825
- *
826
- * @param {any} check Oggetto da controllare
827
- *
828
- * @returns {boolean} Indicazione se l'oggetto è un vero Date di Javascript o no
829
- */
830
- isJsDate(check) {
831
- return check && Object.prototype.toString.call(check) === "[object Date]" && !isNaN(check);
832
- }
833
- /**
834
- * Helper che restituisce **true** qualora l'oggetto passato fosse un DayJs vero e proprio, **false** altrimenti
835
- *
836
- * @param {any} check Oggetto da controllare
837
- * @returns {boolean} Indicazione se l'oggetto è un vero DayJs o no
838
- */
839
- isDayJs(check) {
840
- // Non uso instanceof perché sarebbe estremamente più lento
841
- // Non uso nemmeno isDayjs() della libreria Dayjs dato che ha lo stesso problema: https://github.com/iamkun/dayjs/blob/06f88f425828b1ce96b737332d25145a95a4ee9d/src/index.js#L9
842
- return check.$D !== undefined && check.$M !== undefined && check.$y !== undefined;
843
- }
844
- /**
845
- * Ottiene la formattazione di una data in base alla versione richiesta "small" o "long" e a se stampare o meno i secondi
846
- *
847
- * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
848
- * @param {boolean} small Indica se formattarla con un formato breve (se **true**) o un formato più lungo (se **false**)
849
- *
850
- * @returns {string} Data formattata nel formato richiesto
851
- */
852
- getFormatted(date, small, seconds) {
853
- var date = this.getDateConvertion(date);
854
- if (!date)
855
- return null;
856
- return date.format(small ? this.cfg.smallDate : seconds ? this.cfg.fulldateDisplay : this.cfg.fulldateDisplayNoSS);
857
303
  }
858
304
  }
859
- DateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, deps: [{ token: EXT_LOCALE, optional: true }, { token: EXT_ALLOW_UTC, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
860
- DateServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService });
861
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, decorators: [{
862
- type: Injectable
863
- }], ctorParameters: function () {
864
- return [{ type: undefined, decorators: [{
865
- type: Optional
866
- }, {
867
- type: Inject,
868
- args: [EXT_LOCALE]
869
- }] }, { type: undefined, decorators: [{
870
- type: Optional
871
- }, {
872
- type: Inject,
873
- args: [EXT_ALLOW_UTC]
874
- }] }];
875
- } });
305
+ ExtensionsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
306
+ ExtensionsModulemod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, declarations: [LocDatePipe], imports: [LocalizationModule], exports: [LocDatePipe] });
307
+ ExtensionsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, imports: [LocalizationModule] });
308
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, decorators: [{
309
+ type: NgModule,
310
+ args: [{
311
+ imports: [LocalizationModule],
312
+ declarations: [LocDatePipe],
313
+ exports: [LocDatePipe]
314
+ }]
315
+ }] });
876
316
 
877
317
  /**
878
318
  * Suffisso della proprietà da generare in cui salvare il navigatore
@@ -1303,126 +743,714 @@ class ExportService {
1303
743
  headers.push({ label: lbl ? lbl : prop, key: prop, order: order, type: type, propKey: null });
1304
744
  }
1305
745
  /**
1306
- * Setup per l'esportazione di una lista di valori pivottati dinamicamente:
1307
- *
1308
- * => Recupero il valore utilizzando i navigatori
1309
- *
1310
- * => Recupero l'header utilizzando i navigatori
1311
- *
1312
- * => Con il valore ci creo la property
1313
- *
1314
- * => Con l'header e il riferimento alla property appena creata creo un record negli header da esportare
746
+ * Setup per l'esportazione di una lista di valori pivottati dinamicamente:
747
+ *
748
+ * => Recupero il valore utilizzando i navigatori
749
+ *
750
+ * => Recupero l'header utilizzando i navigatori
751
+ *
752
+ * => Con il valore ci creo la property
753
+ *
754
+ * => Con l'header e il riferimento alla property appena creata creo un record negli header da esportare
755
+ *
756
+ * @param {any} obj Oggetto di cui esportare la proprietà **prop**
757
+ * @param {string} prop Proprietà da esportare
758
+ * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
759
+ */
760
+ parseList(obj, prop, headers) {
761
+ let headernavigator = obj[prop + listCsvHdrPrefix];
762
+ let valuenavigator = obj[prop + listCsvValPrefix];
763
+ let valueformat = obj[prop + listCsvValFormat];
764
+ let order = obj[prop + csvOrdPrefix];
765
+ var jumps, tmpRes;
766
+ var objs = obj[prop];
767
+ for (let idx = 0; idx < objs.length; idx++) {
768
+ let listitem = objs[idx];
769
+ var headersplit = headernavigator.split(" ");
770
+ var header = "";
771
+ // Per l'header si considera a se stante ogni pezzo separato da spazio per fare le concatenazioni
772
+ headersplit.forEach(pr => {
773
+ jumps = pr.split(".");
774
+ tmpRes = JSON.parse(JSON.stringify(listitem));
775
+ jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
776
+ if (!header)
777
+ header = tmpRes;
778
+ else
779
+ header += " " + tmpRes;
780
+ });
781
+ jumps = valuenavigator.split(".");
782
+ tmpRes = JSON.parse(JSON.stringify(listitem));
783
+ jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
784
+ let value = tmpRes;
785
+ let type = "string";
786
+ if (valueformat == "F") {
787
+ let val = value != null ? value.toString() : "";
788
+ val = val.replace(/,/, "");
789
+ value = val.replace(".", ",");
790
+ type = "number";
791
+ }
792
+ else if (valueformat) {
793
+ value = this.dates.getFormatted(obj[prop], valueformat.length <= 10, valueformat.length > 16);
794
+ type = "date";
795
+ }
796
+ Object.defineProperty(obj, prop + idx, { value: value !== null && value !== void 0 ? value : "", writable: false });
797
+ headers.push({ label: header, key: prop + idx, order: order + idx, type: type, propKey: null });
798
+ }
799
+ }
800
+ /**
801
+ * Setup per l'esportazione di una lista di valori pivottati dinamicamente:
802
+ *
803
+ * => Recupero il valore utilizzando i navigatori
804
+ *
805
+ * => Recupero l'header utilizzando i navigatori
806
+ *
807
+ * => Con il valore ci creo la property
808
+ *
809
+ * => Con l'header e il riferimento alla property appena creata creo un record negli header da esportare
810
+ *
811
+ * @param {any} obj Oggetto di cui esportare la proprietà **prop**
812
+ * @param {string} prop Proprietà da esportare
813
+ * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
814
+ */
815
+ parseDictionary(obj, prop, headers) {
816
+ let headernavigator = obj[prop + dictionaryCsvHdrPrefix];
817
+ let valuenavigator = obj[prop + dictionaryCsvValPrefix];
818
+ let order = obj[prop + csvOrdPrefix];
819
+ var jumps, tmpRes;
820
+ var objs = obj[prop];
821
+ for (let idx = 0; idx < objs.length; idx++) {
822
+ let listitem = objs[idx];
823
+ var headersplit = headernavigator.split(" ");
824
+ var header = "";
825
+ headersplit.forEach(pr => {
826
+ jumps = pr.split(".");
827
+ tmpRes = JSON.parse(JSON.stringify(listitem));
828
+ jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
829
+ if (!header)
830
+ header = tmpRes;
831
+ else
832
+ header += " " + tmpRes;
833
+ });
834
+ var valuesplit = valuenavigator.split(",");
835
+ valuesplit.forEach((t, idxinternal) => {
836
+ var navig = t.split("-")[1];
837
+ var desc = t.split("-")[0];
838
+ jumps = navig.split(".");
839
+ tmpRes = JSON.parse(JSON.stringify(listitem));
840
+ jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
841
+ let value = tmpRes;
842
+ let propname = prop + idx.toString() + idxinternal.toString();
843
+ Object.defineProperty(obj, propname, { value: value !== null && value !== void 0 ? value : "", writable: false });
844
+ headers.push({ label: header + " " + desc, key: propname, order: order + idx, type: 'string', propKey: null });
845
+ });
846
+ }
847
+ }
848
+ /**
849
+ * Metodo che si occupa della deserializzazione degli oggetti da esportare. Messo a livello di libreria in modo che qualora ci fosse da cambiare libreria
850
+ * tutte le manutenzioni siano concentrate qui
851
+ *
852
+ * @param {any[]} items Oggetti da deserializzare
853
+ * @param {any} type Tipo da usare come prototipo per la deserializzazione
854
+ *
855
+ * @returns {any} Oggetti deserializzati
856
+ */
857
+ deserializeForExport(items, type) {
858
+ return Deserialize(items, type);
859
+ }
860
+ }
861
+ ExportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, deps: [{ token: DateService }], target: i0.ɵɵFactoryTarget.Injectable });
862
+ ExportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, providedIn: "root" });
863
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, decorators: [{
864
+ type: Injectable,
865
+ args: [{ providedIn: "root" }]
866
+ }], ctorParameters: function () { return [{ type: DateService }]; } });
867
+
868
+ /**
869
+ * Service che fornisce funzionalità di alert nei tipi fondamentali: success, info, warning e danger
870
+ */
871
+ class MessageService {
872
+ /**
873
+ * Costruttore
874
+ *
875
+ * @ignore
876
+ */
877
+ constructor(injector, locProvider) {
878
+ this.injector = injector;
879
+ this.locProvider = locProvider;
880
+ /**
881
+ * Oggetto statico in supporto alla localizzazione
882
+ */
883
+ this.loc = {
884
+ 'Confirm': { 'en-US': "Confirm", 'it-IT': "Conferma", },
885
+ 'Cancel': { 'en-US': "Cancel", 'it-IT': "Annulla", },
886
+ 'Close': { 'en-US': "Close", 'it-IT': "Chiudi", },
887
+ 'Error': { 'en-US': "Error", 'it-IT': "Errore", },
888
+ 'Info': { 'en-US': "Info", 'it-IT': "Informazione", },
889
+ 'Success': { 'en-US': "Success", 'it-IT': "Successo", },
890
+ 'Warning': { 'en-US': "Warning", 'it-IT': "Attenzione", }
891
+ };
892
+ this.init();
893
+ }
894
+ get toastr() {
895
+ return this.injector.get(ToastrService);
896
+ }
897
+ init() {
898
+ return __awaiter(this, void 0, void 0, function* () {
899
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
900
+ this.expiredSessionSwal = swal.mixin({
901
+ showCancelButton: false,
902
+ confirmButtonText: 'Login',
903
+ customClass: {
904
+ confirmButton: "btn btn-primary",
905
+ container: "app-wrap",
906
+ },
907
+ buttonsStyling: false,
908
+ reverseButtons: false,
909
+ allowOutsideClick: false,
910
+ icon: "warning"
911
+ });
912
+ this.successSwalWithCancel = swal.mixin({
913
+ title: this.loc["Success"][LOCALE],
914
+ customClass: {
915
+ confirmButton: "btn btn-primary",
916
+ cancelButton: "btn btn-secondary app-margin-right-10",
917
+ container: "app-wrap",
918
+ },
919
+ buttonsStyling: false,
920
+ reverseButtons: true,
921
+ showCancelButton: true,
922
+ confirmButtonText: this.loc["Confirm"][LOCALE],
923
+ cancelButtonText: this.loc["Cancel"][LOCALE],
924
+ icon: "success"
925
+ });
926
+ this.warningSwalWithCancel = swal.mixin({
927
+ title: this.loc["Warning"][LOCALE],
928
+ customClass: {
929
+ confirmButton: "btn btn-primary",
930
+ cancelButton: "btn btn-secondary app-margin-right-10",
931
+ container: "app-wrap",
932
+ },
933
+ buttonsStyling: false,
934
+ reverseButtons: true,
935
+ showCancelButton: true,
936
+ confirmButtonText: this.loc["Confirm"][LOCALE],
937
+ cancelButtonText: this.loc["Cancel"][LOCALE],
938
+ icon: "warning"
939
+ });
940
+ this.warningSwal = swal.mixin({
941
+ title: this.loc["Warning"][LOCALE],
942
+ customClass: {
943
+ confirmButton: "btn btn-primary",
944
+ container: "app-wrap",
945
+ },
946
+ buttonsStyling: false,
947
+ reverseButtons: true,
948
+ showCancelButton: false,
949
+ confirmButtonText: this.loc["Close"][LOCALE],
950
+ icon: "warning"
951
+ });
952
+ this.successSwal = swal.mixin({
953
+ title: this.loc["Success"][LOCALE],
954
+ customClass: {
955
+ confirmButton: "btn btn-primary",
956
+ container: "app-wrap",
957
+ },
958
+ buttonsStyling: false,
959
+ reverseButtons: true,
960
+ showCancelButton: false,
961
+ confirmButtonText: this.loc["Close"][LOCALE],
962
+ icon: "success"
963
+ });
964
+ this.errorSwal = swal.mixin({
965
+ title: this.loc["Error"][LOCALE],
966
+ customClass: {
967
+ confirmButton: "btn btn-primary",
968
+ container: "app-wrap",
969
+ },
970
+ buttonsStyling: false,
971
+ reverseButtons: true,
972
+ showCancelButton: false,
973
+ confirmButtonText: this.loc["Close"][LOCALE],
974
+ icon: "error"
975
+ });
976
+ this.infoSwal = swal.mixin({
977
+ title: this.loc["Info"][LOCALE],
978
+ customClass: {
979
+ confirmButton: "btn btn-primary",
980
+ container: "app-wrap",
981
+ },
982
+ buttonsStyling: false,
983
+ reverseButtons: true,
984
+ showCancelButton: false,
985
+ confirmButtonText: this.loc["Close"][LOCALE],
986
+ icon: "info"
987
+ });
988
+ });
989
+ }
990
+ /**
991
+ * Presentazione di un semplice messaggio di successo
992
+ *
993
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
994
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
995
+ *
996
+ * @param {string} text Testo da mostrare
997
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
998
+ */
999
+ simpleSuccess(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
1000
+ let tos = this.toastrOrSwal(secondaryNotificationType);
1001
+ if (tos == "swal")
1002
+ this.successSwal.fire("", text);
1003
+ else
1004
+ 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 });
1005
+ }
1006
+ /**
1007
+ * Presentazione di un semplice messaggio di informazione
1008
+ *
1009
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
1010
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
1011
+ *
1012
+ * @param {string} text Testo da mostrare
1013
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
1014
+ */
1015
+ simpleInfo(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
1016
+ let tos = this.toastrOrSwal(secondaryNotificationType);
1017
+ if (tos == "swal")
1018
+ this.infoSwal.fire("", text);
1019
+ else
1020
+ 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 });
1021
+ }
1022
+ /**
1023
+ * Presentazione di un semplice messaggio di errore
1024
+ *
1025
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
1026
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
1027
+ *
1028
+ * @param {string} text Testo da mostrare
1029
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
1030
+ */
1031
+ simpleError(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
1032
+ let tos = this.toastrOrSwal(secondaryNotificationType);
1033
+ if (tos == "swal")
1034
+ this.errorSwal.fire("", text);
1035
+ else
1036
+ 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 });
1037
+ }
1038
+ /**
1039
+ * Presentazione di un semplice messaggio di avviso
1040
+ *
1041
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
1042
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
1043
+ *
1044
+ * @param {string} text Testo da mostrare
1045
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
1046
+ */
1047
+ simpleWarning(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
1048
+ let tos = this.toastrOrSwal(secondaryNotificationType);
1049
+ if (tos == "swal")
1050
+ this.warningSwal.fire("", text);
1051
+ else
1052
+ 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 });
1053
+ }
1054
+ /**
1055
+ * Ripulisce tutti i messaggi presenti in un dato momento sullo schermo
1056
+ */
1057
+ clearMessages() {
1058
+ this.toastr.clear();
1059
+ swal.close();
1060
+ }
1061
+ /**
1062
+ * Mostra un messaggio di avviso con richiesta di conferma
1063
+ *
1064
+ * @param {string} title Titolo del messaggio
1065
+ * @param {string} text Contenuto del messaggio
1066
+ *
1067
+ * @returns {Promise} Restituisce una Promise col risultato scelto dall'utente (conferma o no)
1068
+ */
1069
+ promiseWarningWithChoice(title, text) {
1070
+ return this.warningSwalWithCancel.fire(title, text);
1071
+ }
1072
+ /**
1073
+ * In base alla configurazione attuale e all'eventuale override per la chiamata del caso indica se bisogna utilizzare toastr o sweetalert
1074
+ *
1075
+ * @param {"toastr" | "swal" | null} providerOverride Override alla modalità configurata
1076
+ *
1077
+ * @returns {"toastr" | "swal"} Indicazione su che provider di messaggi di avviso debba essere utilizzato
1078
+ */
1079
+ toastrOrSwal(providerOverride) {
1080
+ if (providerOverride != null)
1081
+ return providerOverride;
1082
+ return "swal";
1083
+ }
1084
+ /**
1085
+ * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
1086
+ *
1087
+ * @param {string} title Titolo del messaggio
1088
+ * @param {string} text Contenuto del messaggio
1089
+ * @param {Function} onsuccess Callback da chimare su conferma
1090
+ * @param {Function} onerror Callback da chimare su errori
1091
+ */
1092
+ simpleWarningWithChoice(title, text, onsuccess = null, onerror = null) {
1093
+ this.warningSwalWithCancel.fire(title, text).then((result) => {
1094
+ if (result.value && onsuccess)
1095
+ onsuccess();
1096
+ else if (onerror)
1097
+ onerror();
1098
+ });
1099
+ }
1100
+ /**
1101
+ * Mostra un messaggio di success con richiesta di conferma e gestisce il risultato chiamato i callback **onconfirm** o **onabort**
1102
+ *
1103
+ * @param {string} title Titolo del messaggio
1104
+ * @param {string} text Contenuto del messaggio
1105
+ * @param {Function} onconfirm Callback da chimare su conferma
1106
+ * @param {Function} onabort Callback da chimare su annullamento
1107
+ * @param {string} confirmtext Testo del pulsante di azione
1108
+ * @param {string} aborttext Testo del pulsante di annullamento
1109
+ */
1110
+ simpleSuccessWithChoice(title, text, onconfirm = null, onabort = null, confirmtext = "", aborttext = '') {
1111
+ var configuration = {
1112
+ title: title,
1113
+ html: text
1114
+ };
1115
+ if (confirmtext)
1116
+ configuration["confirmButtonText"] = confirmtext;
1117
+ if (aborttext)
1118
+ configuration["cancelButtonText"] = aborttext;
1119
+ this.successSwalWithCancel.fire(configuration).then((result) => {
1120
+ if (result.value && onconfirm)
1121
+ onconfirm();
1122
+ else if (onabort)
1123
+ onabort();
1124
+ });
1125
+ }
1126
+ /**
1127
+ * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
1128
+ *
1129
+ * @param {string} title Titolo del messaggio
1130
+ * @param {string} text Contenuto del messaggio
1131
+ */
1132
+ observableSimpleWarningWithChoice(title, text) {
1133
+ return of(this.warningSwalWithCancel.fire(title, text)).pipe(map(t => !!t.value));
1134
+ }
1135
+ /**
1136
+ * Mostra un messaggio di avviso che la sessione corrente è scaduta e propone all'utente di navigare al login. Qualora l'utente decidesse di farlo
1137
+ * verrà chiamata la funzione di callback **onnavigate
1138
+ *
1139
+ * @param {string} title Titolo del messaggio
1140
+ * @param {string} text Contenuto del messaggio
1141
+ * @param {Function} onnavigate Callback da chimare su navigazione in corso
1142
+ */
1143
+ expiredSessionMessage(title, text, onnavigate = null) {
1144
+ this.expiredSessionSwal.fire(title, text).then((result) => {
1145
+ if (result.value && onnavigate)
1146
+ onnavigate();
1147
+ });
1148
+ }
1149
+ /**
1150
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **CallResult**
1151
+ *
1152
+ * @param {CallResult} response Risposta ricevuta dal server
1153
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
1154
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
1155
+ * @param {Function} postSuccess Callback da chimare in caso di successo
1156
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
1157
+ */
1158
+ manageCallResultResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
1159
+ if (response.success) {
1160
+ if (response.haswarning)
1161
+ this.simpleWarning(response.warning);
1162
+ else if (successMsg)
1163
+ this.simpleSuccess(successMsg);
1164
+ if (postSuccess)
1165
+ postSuccess();
1166
+ }
1167
+ else {
1168
+ this.simpleError((errorMsg ? errorMsg + ": " : "") + response.haserror ? response.error : '[NO ERR.]');
1169
+ if (postFailure)
1170
+ postFailure();
1171
+ }
1172
+ }
1173
+ /**
1174
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **string**, considerando che:
1175
+ *
1176
+ * Stringa vuota --> Tutto bene
1177
+ *
1178
+ * Stringa piena --> Questo è il messaggio d'errore per cui la chiamata è fallita
1179
+ *
1180
+ * @param {string} response Risposta ricevuta dal server
1181
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
1182
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
1183
+ * @param {Function} postSuccess Callback da chimare in caso di successo
1184
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
1185
+ */
1186
+ manageStringResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
1187
+ if (!response) {
1188
+ if (successMsg)
1189
+ this.simpleSuccess(successMsg);
1190
+ if (postSuccess)
1191
+ postSuccess();
1192
+ }
1193
+ else {
1194
+ if (errorMsg)
1195
+ this.simpleError(errorMsg + ": " + response);
1196
+ if (postFailure)
1197
+ postFailure();
1198
+ }
1199
+ }
1200
+ /**
1201
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **boolean**
1202
+ *
1203
+ * @param {string} response Risposta ricevuta dal server
1204
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
1205
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
1206
+ * @param {Function} postSuccess Callback da chimare in caso di successo
1207
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
1208
+ */
1209
+ manageStringResponseBool(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
1210
+ if (response) {
1211
+ if (successMsg)
1212
+ this.simpleSuccess(successMsg);
1213
+ if (postSuccess)
1214
+ postSuccess();
1215
+ }
1216
+ else {
1217
+ if (errorMsg)
1218
+ this.simpleError(errorMsg);
1219
+ if (postFailure)
1220
+ postFailure();
1221
+ }
1222
+ }
1223
+ }
1224
+ MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, deps: [{ token: Injector }, { token: i1.BaseLocalization, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1225
+ MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, providedIn: "root" });
1226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, decorators: [{
1227
+ type: Injectable,
1228
+ args: [{ providedIn: "root" }]
1229
+ }], ctorParameters: function () {
1230
+ return [{ type: i0.Injector, decorators: [{
1231
+ type: Inject,
1232
+ args: [Injector]
1233
+ }] }, { type: i1.BaseLocalization, decorators: [{
1234
+ type: Optional
1235
+ }] }];
1236
+ } });
1237
+
1238
+ /**
1239
+ * Service che fornisce un accesso base in lettura/scrittura sulla clipboard
1240
+ */
1241
+ class ClipboardService {
1242
+ /**
1243
+ * Costruttore
1244
+ *
1245
+ * @ignore
1246
+ */
1247
+ constructor(msgService, locProvider) {
1248
+ this.msgService = msgService;
1249
+ this.locProvider = locProvider;
1250
+ /**
1251
+ * Oggetto statico di localizzazione per i messaggi di questa Service
1252
+ */
1253
+ this.loc = {
1254
+ "Unfortunately Firefox doesn't yet support direct Clipboard access if not via extensions, Please use Chrome to do this operation": {
1255
+ 'en-US': "Unfortunately Firefox doesn't yet support direct Clipboard access if not via extensions, Please use Chrome to do this operation",
1256
+ 'it-IT': "Mi dispiace ma Firefox non supporta l'accesso diretto alla Clipboard, se non attraverso le estensioni. Si prega di usare Chrome"
1257
+ },
1258
+ "Generic error during 'copy' command execution": {
1259
+ 'en-US': "Generic error during 'copy' command execution",
1260
+ 'it-IT': "Errore generico durante l'esecuzione del comando 'copy'"
1261
+ },
1262
+ "Error during Clipboard content read operation": {
1263
+ 'en-US': "Error during Clipboard content read operation",
1264
+ 'it-IT': "Errore nella lettura del contenuto della Clipboard"
1265
+ },
1266
+ "Error during Clipboard content copy operation": {
1267
+ 'en-US': "Error during Clipboard content copy operation",
1268
+ 'it-IT': "Errore nella scrittura del contenuto nella Clipboard"
1269
+ },
1270
+ "Please insert your clipboard content": {
1271
+ 'en-US': "Please insert your clipboard content",
1272
+ 'it-IT': "Si prega di incollare il contenuto della Clipboard"
1273
+ },
1274
+ "User input required": {
1275
+ 'en-US': "User input required",
1276
+ 'it-IT': "Richiesto Input utente"
1277
+ },
1278
+ "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": {
1279
+ '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",
1280
+ '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"
1281
+ },
1282
+ "Confirm": {
1283
+ 'en-US': "Confirm",
1284
+ 'it-IT': "Conferma"
1285
+ },
1286
+ "Cancel": {
1287
+ 'en-US': "Cancel",
1288
+ 'it-IT': "Annulla"
1289
+ },
1290
+ };
1291
+ }
1292
+ /**
1293
+ * Prende il valore della clipboard.
1294
+ * Si può specificare se ci si aspetta una lista o una matrice di valori in modo da ricevere già un risultato utilizzabile
1315
1295
  *
1316
- * @param {any} obj Oggetto di cui esportare la proprietà **prop**
1317
- * @param {string} prop Proprietà da esportare
1318
- * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
1296
+ * @param {'array' | 'matrix'} style Stile dell'output desiderato, se array o matrice
1297
+ * @param {Function} valueFoundCallback Callback che questa funzione chiamerà una volta ottenuto i valori richiesti dalla clipboard
1319
1298
  */
1320
- parseList(obj, prop, headers) {
1321
- let headernavigator = obj[prop + listCsvHdrPrefix];
1322
- let valuenavigator = obj[prop + listCsvValPrefix];
1323
- let valueformat = obj[prop + listCsvValFormat];
1324
- let order = obj[prop + csvOrdPrefix];
1325
- var jumps, tmpRes;
1326
- var objs = obj[prop];
1327
- for (let idx = 0; idx < objs.length; idx++) {
1328
- let listitem = objs[idx];
1329
- var headersplit = headernavigator.split(" ");
1330
- var header = "";
1331
- // Per l'header si considera a se stante ogni pezzo separato da spazio per fare le concatenazioni
1332
- headersplit.forEach(pr => {
1333
- jumps = pr.split(".");
1334
- tmpRes = JSON.parse(JSON.stringify(listitem));
1335
- jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
1336
- if (!header)
1337
- header = tmpRes;
1338
- else
1339
- header += " " + tmpRes;
1340
- });
1341
- jumps = valuenavigator.split(".");
1342
- tmpRes = JSON.parse(JSON.stringify(listitem));
1343
- jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
1344
- let value = tmpRes;
1345
- let type = "string";
1346
- if (valueformat == "F") {
1347
- let val = value != null ? value.toString() : "";
1348
- val = val.replace(/,/, "");
1349
- value = val.replace(".", ",");
1350
- type = "number";
1299
+ getClipboard(style, valueFoundCallback) {
1300
+ return __awaiter(this, void 0, void 0, function* () {
1301
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
1302
+ if (navigator.userAgent.indexOf("Firefox") != -1) {
1303
+ swal.fire({
1304
+ title: this.loc["User input required"][LOCALE],
1305
+ 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],
1306
+ input: 'textarea',
1307
+ icon: "warning",
1308
+ confirmButtonText: this.loc["Confirm"][LOCALE],
1309
+ cancelButtonText: this.loc["Cancel"][LOCALE],
1310
+ showCancelButton: true,
1311
+ customClass: {
1312
+ confirmButton: "btn btn-primary",
1313
+ cancelButton: "btn btn-secondary app-margin-right-15",
1314
+ container: "app-wrap",
1315
+ },
1316
+ reverseButtons: true,
1317
+ allowOutsideClick: false,
1318
+ inputValidator: (value) => {
1319
+ if (!value)
1320
+ return this.loc["Please insert your clipboard content"][LOCALE];
1321
+ }
1322
+ }).then(t => {
1323
+ if (t.isConfirmed) {
1324
+ console.log("[@esfaenza/extensions] Retrieving input data from user input");
1325
+ this.doClipboardDataGet(t.value, style, valueFoundCallback);
1326
+ }
1327
+ });
1328
+ return;
1351
1329
  }
1352
- else if (valueformat) {
1353
- value = this.dates.getFormatted(obj[prop], valueformat.length <= 10, valueformat.length > 16);
1354
- type = "date";
1330
+ if (window.clipboardData) {
1331
+ console.log("[@esfaenza/extensions] Found clipboardData");
1332
+ let data = window.clipboardData.getData("Text");
1333
+ this.doClipboardDataGet(data, style, valueFoundCallback);
1355
1334
  }
1356
- Object.defineProperty(obj, prop + idx, { value: value !== null && value !== void 0 ? value : "", writable: false });
1357
- headers.push({ label: header, key: prop + idx, order: order + idx, type: type, propKey: null });
1358
- }
1335
+ else if (window.navigator.clipboard) {
1336
+ console.log("[@esfaenza/extensions] Found navigator clipboard");
1337
+ window.navigator.permissions.query({ name: 'clipboard-read' }).then(result => {
1338
+ if (!(result.state === 'granted' || result.state === 'prompt')) {
1339
+ console.error("[@esfaenza/extensions] Clipboard permission not granted");
1340
+ if (valueFoundCallback)
1341
+ valueFoundCallback([]);
1342
+ return;
1343
+ }
1344
+ console.log("[@esfaenza/extensions] Clipboard permission granted, retrieving values");
1345
+ window.navigator.clipboard.readText()
1346
+ .then((t) => this.doClipboardDataGet(t, style, valueFoundCallback))
1347
+ .catch((err) => this.msgService.simpleError(this.loc["Error during Clipboard content read operation"][LOCALE] + ": " + err));
1348
+ });
1349
+ }
1350
+ });
1351
+ }
1352
+ /** @ignore */
1353
+ doClipboardDataGet(clipboardText, style, valueFoundCallback) {
1354
+ console.log("[@esfaenza/extensions] Retrieved clipboard values: " + clipboardText);
1355
+ let value = style == "array" ? this.getClipboardLines(clipboardText) :
1356
+ style == "matrix" ? this.getClipboardMatrix(clipboardText) : [];
1357
+ console.log(`[@esfaenza/extensions] Adapted for ${style}: ${JSON.stringify(value)}`);
1358
+ if (valueFoundCallback)
1359
+ valueFoundCallback(value);
1359
1360
  }
1360
1361
  /**
1361
- * Setup per l'esportazione di una lista di valori pivottati dinamicamente:
1362
- *
1363
- * => Recupero il valore utilizzando i navigatori
1362
+ * Ottiene il contenuto della clipboard diviso per righe (separate da newline)
1364
1363
  *
1365
- * => Recupero l'header utilizzando i navigatori
1364
+ * @param {string} data contenuto letto dalla clipboard
1366
1365
  *
1367
- * => Con il valore ci creo la property
1366
+ * @returns {string[]} Array contenente il testo preso dalla clipboard diviso per riga
1367
+ */
1368
+ getClipboardLines(data) {
1369
+ let trimmedData = data.trim();
1370
+ if (!trimmedData.includes("\r\n") && trimmedData.includes("\n"))
1371
+ return trimmedData.split("\n");
1372
+ return trimmedData.split("\r\n");
1373
+ }
1374
+ /**
1375
+ * Ottiene il contenuto della clipboard diviso per righe (separate da newline) e colonne (separate da tab)
1368
1376
  *
1369
- * => Con l'header e il riferimento alla property appena creata creo un record negli header da esportare
1377
+ * @param {string} data contenuto letto dalla clipboard
1370
1378
  *
1371
- * @param {any} obj Oggetto di cui esportare la proprietà **prop**
1372
- * @param {string} prop Proprietà da esportare
1373
- * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
1379
+ * @returns {string[][]} Matrice contenente il testo preso dalla clipboard diviso per riga e colonna
1374
1380
  */
1375
- parseDictionary(obj, prop, headers) {
1376
- let headernavigator = obj[prop + dictionaryCsvHdrPrefix];
1377
- let valuenavigator = obj[prop + dictionaryCsvValPrefix];
1378
- let order = obj[prop + csvOrdPrefix];
1379
- var jumps, tmpRes;
1380
- var objs = obj[prop];
1381
- for (let idx = 0; idx < objs.length; idx++) {
1382
- let listitem = objs[idx];
1383
- var headersplit = headernavigator.split(" ");
1384
- var header = "";
1385
- headersplit.forEach(pr => {
1386
- jumps = pr.split(".");
1387
- tmpRes = JSON.parse(JSON.stringify(listitem));
1388
- jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
1389
- if (!header)
1390
- header = tmpRes;
1391
- else
1392
- header += " " + tmpRes;
1393
- });
1394
- var valuesplit = valuenavigator.split(",");
1395
- valuesplit.forEach((t, idxinternal) => {
1396
- var navig = t.split("-")[1];
1397
- var desc = t.split("-")[0];
1398
- jumps = navig.split(".");
1399
- tmpRes = JSON.parse(JSON.stringify(listitem));
1400
- jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
1401
- let value = tmpRes;
1402
- let propname = prop + idx.toString() + idxinternal.toString();
1403
- Object.defineProperty(obj, propname, { value: value !== null && value !== void 0 ? value : "", writable: false });
1404
- headers.push({ label: header + " " + desc, key: propname, order: order + idx, type: 'string', propKey: null });
1405
- });
1406
- }
1381
+ getClipboardMatrix(data) {
1382
+ var ret = [];
1383
+ var rows = !data.includes("\r\n") && data.includes("\n") ? data.split("\n") : data.split("\r\n");
1384
+ // A quanto pare ogni valore è separato da un \t... spero che sia uno standard di quando si copia da excel altrimenti ciao
1385
+ for (let i = 0; i < rows.length; i++)
1386
+ ret.push(rows[i].split('\t').map(t => t.trim()));
1387
+ return ret;
1407
1388
  }
1408
1389
  /**
1409
- * Metodo che si occupa della deserializzazione degli oggetti da esportare. Messo a livello di libreria in modo che qualora ci fosse da cambiare libreria
1410
- * tutte le manutenzioni siano concentrate qui
1411
- *
1412
- * @param {any[]} items Oggetti da deserializzare
1413
- * @param {any} type Tipo da usare come prototipo per la deserializzazione
1390
+ * Metodo che copia un testo all'interno della clipboard
1414
1391
  *
1415
- * @returns {any} Oggetti deserializzati
1392
+ * @param {string} text Testo da inserire nella clipboard
1416
1393
  */
1417
- deserializeForExport(items, type) {
1418
- return Deserialize(items, type);
1394
+ copyTextToClipboard(text) {
1395
+ return __awaiter(this, void 0, void 0, function* () {
1396
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
1397
+ var textArea = document.createElement("textarea");
1398
+ //
1399
+ // *** This styling is an extra step which is likely not required. ***
1400
+ //
1401
+ // Why is it here? To ensure:
1402
+ // 1. the element is able to have focus and selection.
1403
+ // 2. if element was to flash render it has minimal visual impact.
1404
+ // 3. less flakyness with selection and copying which **might** occur if
1405
+ // the textarea element is not visible.
1406
+ //
1407
+ // The likelihood is the element won't even render, not even a flash,
1408
+ // so some of these are just precautions. However in IE the element
1409
+ // is visible whilst the popup box asking the user for permission for
1410
+ // the web page to copy to the clipboard.
1411
+ //
1412
+ // Place in top-left corner of screen regardless of scroll position.
1413
+ textArea.style.position = "fixed";
1414
+ textArea.style.top = "0";
1415
+ textArea.style.left = "0";
1416
+ // Ensure it has a small width and height. Setting to 1px / 1em
1417
+ // doesn't work as this gives a negative w/h on some browsers.
1418
+ textArea.style.width = "2em";
1419
+ textArea.style.height = "2em";
1420
+ // We don't need padding, reducing the size if it does flash render.
1421
+ textArea.style.padding = "0";
1422
+ // Clean up any borders.
1423
+ textArea.style.border = "none";
1424
+ textArea.style.outline = "none";
1425
+ textArea.style.boxShadow = "none";
1426
+ // Avoid flash of white box if rendered for any reason.
1427
+ textArea.style.background = "transparent";
1428
+ textArea.value = text;
1429
+ document.body.appendChild(textArea);
1430
+ textArea.focus();
1431
+ textArea.select();
1432
+ try {
1433
+ var successful = document.execCommand("copy");
1434
+ if (!successful)
1435
+ this.msgService.simpleError(this.loc["Generic error during 'copy' command execution"][LOCALE]);
1436
+ }
1437
+ catch (err) {
1438
+ this.msgService.simpleError(this.loc["Error during Clipboard content copy operation"][LOCALE] + ": " + err);
1439
+ }
1440
+ document.body.removeChild(textArea);
1441
+ });
1419
1442
  }
1420
1443
  }
1421
- ExportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, deps: [{ token: DateService }], target: i0.ɵɵFactoryTarget.Injectable });
1422
- ExportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService });
1423
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, decorators: [{
1424
- type: Injectable
1425
- }], ctorParameters: function () { return [{ type: DateService }]; } });
1444
+ 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 });
1445
+ ClipboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, providedIn: "root" });
1446
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, decorators: [{
1447
+ type: Injectable,
1448
+ args: [{ providedIn: "root" }]
1449
+ }], ctorParameters: function () {
1450
+ return [{ type: MessageService }, { type: i1.BaseLocalization, decorators: [{
1451
+ type: Optional
1452
+ }] }];
1453
+ } });
1426
1454
 
1427
1455
  // Angular
1428
1456
  /**
@@ -1726,9 +1754,10 @@ class HashingService {
1726
1754
  }
1727
1755
  }
1728
1756
  HashingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1729
- HashingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService });
1757
+ HashingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService, providedIn: "root" });
1730
1758
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService, decorators: [{
1731
- type: Injectable
1759
+ type: Injectable,
1760
+ args: [{ providedIn: "root" }]
1732
1761
  }] });
1733
1762
 
1734
1763
  /**
@@ -1977,11 +2006,37 @@ class UtilityService {
1977
2006
  }
1978
2007
  }
1979
2008
  UtilityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1980
- UtilityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService });
2009
+ UtilityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService, providedIn: "root" });
1981
2010
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService, decorators: [{
1982
- type: Injectable
2011
+ type: Injectable,
2012
+ args: [{ providedIn: "root" }]
1983
2013
  }] });
1984
2014
 
2015
+ /**
2016
+ * Classe che rappresenta una risposta ricevuta da un Backend
2017
+ */
2018
+ class CallResult {
2019
+ }
2020
+
2021
+ /**
2022
+ * Header per il file CSV che sta venendo generato
2023
+ */
2024
+ class CsvHeaders {
2025
+ }
2026
+
2027
+ /**
2028
+ * Rappresentazione di un oggetto generico
2029
+ */
2030
+ class GenericItem {
2031
+ }
2032
+
2033
+ /** Enumeratore dei tipi di messaggio che i moduli esterni possono contattare sull'applicazione principale */
2034
+ var InboundMessageTypes;
2035
+ (function (InboundMessageTypes) {
2036
+ /** Evento di navigazione */
2037
+ InboundMessageTypes[InboundMessageTypes["Navigation"] = 0] = "Navigation";
2038
+ })(InboundMessageTypes || (InboundMessageTypes = {}));
2039
+
1985
2040
  /** Classe che rappresenta un generico messaggio scambiato fra applicazione e moduli */
1986
2041
  class InterComMessage {
1987
2042
  /**
@@ -2038,76 +2093,12 @@ class InterComService {
2038
2093
  }
2039
2094
  }
2040
2095
  InterComService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2041
- InterComService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService });
2096
+ InterComService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService, providedIn: "root" });
2042
2097
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService, decorators: [{
2043
- type: Injectable
2044
- }] });
2045
-
2046
- // Angular
2047
- /**
2048
- * Modulo di estensione che registra autonomamente **TUTTI** i servizi di estensione:
2049
- * ClipboardService,
2050
- * DateService,
2051
- * ExportService,
2052
- * HashingService,
2053
- * MessageService,
2054
- * UtilityService
2055
- * InterComService
2056
- *
2057
- * con eventuali provider che utilizzano
2058
- */
2059
- class FullExtensionsModule {
2060
- static forRoot(config) {
2061
- return {
2062
- ngModule: FullExtensionsModule,
2063
- providers: [
2064
- ClipboardService,
2065
- DateService,
2066
- ExportService,
2067
- HashingService,
2068
- MessageService,
2069
- UtilityService,
2070
- InterComService,
2071
- { provide: EXT_LOCALE, useValue: (config === null || config === void 0 ? void 0 : config.locale) || 'it-IT' },
2072
- { provide: EXT_FANCY_ALERTS, useValue: (config === null || config === void 0 ? void 0 : config.fancy_alerts) || true },
2073
- { provide: APPSEARCH_PREFIX, useValue: (config === null || config === void 0 ? void 0 : config.appsearch_prefix) || 'Hot' },
2074
- { 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 }
2075
- ]
2076
- };
2077
- }
2078
- }
2079
- FullExtensionsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FullExtensionsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2080
- FullExtensionsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FullExtensionsModule });
2081
- FullExtensionsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FullExtensionsModule });
2082
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FullExtensionsModule, decorators: [{
2083
- type: NgModule
2098
+ type: Injectable,
2099
+ args: [{ providedIn: "root" }]
2084
2100
  }] });
2085
2101
 
2086
- /**
2087
- * Classe che rappresenta una risposta ricevuta da un Backend
2088
- */
2089
- class CallResult {
2090
- }
2091
-
2092
- /**
2093
- * Header per il file CSV che sta venendo generato
2094
- */
2095
- class CsvHeaders {
2096
- }
2097
-
2098
- /**
2099
- * Rappresentazione di un oggetto generico
2100
- */
2101
- class GenericItem {
2102
- }
2103
-
2104
- /** Enumeratore dei tipi di messaggio che i moduli esterni possono contattare sull'applicazione principale */
2105
- var InboundMessageTypes;
2106
- (function (InboundMessageTypes) {
2107
- /** Evento di navigazione */
2108
- InboundMessageTypes[InboundMessageTypes["Navigation"] = 0] = "Navigation";
2109
- })(InboundMessageTypes || (InboundMessageTypes = {}));
2110
-
2111
2102
  /*
2112
2103
  * Public API Surface of extensions
2113
2104
  */
@@ -2116,5 +2107,5 @@ var InboundMessageTypes;
2116
2107
  * Generated bundle index. Do not edit.
2117
2108
  */
2118
2109
 
2119
- export { APPSEARCH_PREFIX, CallResult, ClipboardService, CsvHeaders, DateService, EXT_ALLOW_UTC, EXT_FANCY_ALERTS, EXT_LOCALE, Export, ExportAs, ExportDictionary, ExportList, ExportService, ExtensionsModule, FullExtensionsModule, GenericItem, HashingService, InboundMessageTypes, InterComMessage, InterComService, MessageService, UtilityService };
2110
+ export { APPSEARCH_PREFIX, CallResult, ClipboardService, CsvHeaders, DateService, EXT_ALLOW_UTC, Export, ExportAs, ExportDictionary, ExportList, ExportService, ExtensionsModule, GenericItem, HashingService, InboundMessageTypes, InterComMessage, InterComService, LocDatePipe, MessageService, UtilityService };
2120
2111
  //# sourceMappingURL=esfaenza-extensions.mjs.map