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