newportsite 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/newportsite-1.1.3.tgz +0 -0
  2. package/ng-package.json +7 -0
  3. package/obfuscate.js +70 -0
  4. package/package.json +15 -0
  5. package/src/lib/app.component.ts +47 -0
  6. package/src/lib/app.routing.ts +38 -0
  7. package/src/lib/auth/alert.component.html +5 -0
  8. package/src/lib/auth/alert.component.ts +24 -0
  9. package/src/lib/auth/auth.component.html +1 -0
  10. package/src/lib/auth/auth.component.ts +10 -0
  11. package/src/lib/auth/auth.routes.ts +16 -0
  12. package/src/lib/auth/index.ts +4 -0
  13. package/src/lib/auth/login.component.html +87 -0
  14. package/src/lib/auth/login.component.ts +158 -0
  15. package/src/lib/auth/models/index.ts +1 -0
  16. package/src/lib/auth/models/user.ts +25 -0
  17. package/src/lib/auth/register.component.html +157 -0
  18. package/src/lib/auth/register.component.ts +219 -0
  19. package/src/lib/auth/services/alert.service.ts +47 -0
  20. package/src/lib/auth/services/auth.service.ts +28 -0
  21. package/src/lib/auth/services/index.ts +3 -0
  22. package/src/lib/auth/services/user.service.spec.ts +112 -0
  23. package/src/lib/auth/services/user.service.ts +47 -0
  24. package/src/lib/common/card.component.html +72 -0
  25. package/src/lib/common/card.component.ts +102 -0
  26. package/src/lib/common/commands.component.html +8 -0
  27. package/src/lib/common/commands.component.ts +42 -0
  28. package/src/lib/common/context.component.html +9 -0
  29. package/src/lib/common/context.component.ts +38 -0
  30. package/src/lib/common/grid.component.html +20 -0
  31. package/src/lib/common/grid.component.ts +747 -0
  32. package/src/lib/common/index.ts +9 -0
  33. package/src/lib/common/loader.component.html +5 -0
  34. package/src/lib/common/loader.component.ts +27 -0
  35. package/src/lib/common/lookup.component.html +29 -0
  36. package/src/lib/common/lookup.component.ts +115 -0
  37. package/src/lib/common/messagebox.component.html +39 -0
  38. package/src/lib/common/messagebox.component.ts +74 -0
  39. package/src/lib/common/theme-toggle.component.ts +139 -0
  40. package/src/lib/config.ts +62 -0
  41. package/src/lib/containers/default-layout/default-layout.component.html +191 -0
  42. package/src/lib/containers/default-layout/default-layout.component.ts +158 -0
  43. package/src/lib/containers/default-layout/index.ts +1 -0
  44. package/src/lib/containers/index.ts +1 -0
  45. package/src/lib/directives/component.draggable.ts +80 -0
  46. package/src/lib/directives/index.ts +2 -0
  47. package/src/lib/directives/input.directive.spec.ts +158 -0
  48. package/src/lib/directives/input.directive.ts +210 -0
  49. package/src/lib/home/dashboard/dashboard.component.html +38 -0
  50. package/src/lib/home/dashboard/dashboard.component.ts +50 -0
  51. package/src/lib/home/dashboard/index.ts +1 -0
  52. package/src/lib/home/index.component.html +1 -0
  53. package/src/lib/home/index.component.ts +10 -0
  54. package/src/lib/home/index.routes.ts +29 -0
  55. package/src/lib/home/index.ts +1 -0
  56. package/src/lib/home/info/index.ts +1 -0
  57. package/src/lib/home/info/info.component.css +476 -0
  58. package/src/lib/home/info/info.component.html +174 -0
  59. package/src/lib/home/info/info.component.ts +287 -0
  60. package/src/lib/home/model/article.component.html +10 -0
  61. package/src/lib/home/model/article.component.ts +50 -0
  62. package/src/lib/home/model/barchart.component.html +8 -0
  63. package/src/lib/home/model/barchart.component.ts +59 -0
  64. package/src/lib/home/model/index.ts +7 -0
  65. package/src/lib/home/model/itemdetail.component.html +25 -0
  66. package/src/lib/home/model/itemdetail.component.ts +93 -0
  67. package/src/lib/home/model/itemtab.component.html +25 -0
  68. package/src/lib/home/model/itemtab.component.ts +105 -0
  69. package/src/lib/home/model/model.component.html +121 -0
  70. package/src/lib/home/model/model.component.ts +510 -0
  71. package/src/lib/home/model/modeltoolbar.component.html +111 -0
  72. package/src/lib/home/model/modeltoolbar.component.ts +157 -0
  73. package/src/lib/home/model/navigation.component.html +86 -0
  74. package/src/lib/home/model/navigation.component.ts +247 -0
  75. package/src/lib/home/model/services/index.ts +1 -0
  76. package/src/lib/home/model/services/model.service.spec.ts +423 -0
  77. package/src/lib/home/model/services/model.service.ts +319 -0
  78. package/src/lib/home/modelsearch/index.ts +1 -0
  79. package/src/lib/home/modelsearch/modelsearch.component.html +124 -0
  80. package/src/lib/home/modelsearch/modelsearch.component.ts +453 -0
  81. package/src/lib/interfaces/data.interface.ts +131 -0
  82. package/src/lib/interfaces/index.ts +2 -0
  83. package/src/lib/interfaces/item.interface.ts +438 -0
  84. package/src/lib/players/lookup/lookup.directive.ts +6 -0
  85. package/src/lib/players/lookup/lookup.item.component.ts +37 -0
  86. package/src/lib/players/lookup/lookup.item.ts +9 -0
  87. package/src/lib/players/lookup/lookup.player.component.ts +59 -0
  88. package/src/lib/players/lookup/lookup.selector.component.ts +41 -0
  89. package/src/lib/players/model/model.directive.ts +6 -0
  90. package/src/lib/players/model/model.item.component.spec.ts +311 -0
  91. package/src/lib/players/model/model.item.component.ts +3457 -0
  92. package/src/lib/players/model/model.item.ts +9 -0
  93. package/src/lib/players/model/model.player.component.ts +109 -0
  94. package/src/lib/players/model/model.selector.component.ts +59 -0
  95. package/src/lib/scheduler/scheduler.component.html +13 -0
  96. package/src/lib/scheduler/scheduler.component.scss +6 -0
  97. package/src/lib/scheduler/scheduler.component.ts +296 -0
  98. package/src/lib/scheduler/scheduler.routes.ts +15 -0
  99. package/src/lib/scheduler/schedulerdialog.component.html +72 -0
  100. package/src/lib/scheduler/schedulerdialog.component.ts +208 -0
  101. package/src/lib/scheduler/services/scheduler.service.ts +133 -0
  102. package/src/lib/services/auth-state.service.ts +129 -0
  103. package/src/lib/services/auth.interceptor.spec.ts +144 -0
  104. package/src/lib/services/auth.interceptor.ts +44 -0
  105. package/src/lib/services/cache.service.spec.ts +143 -0
  106. package/src/lib/services/cache.service.ts +71 -0
  107. package/src/lib/services/global-error-handler.spec.ts +39 -0
  108. package/src/lib/services/global-error-handler.ts +28 -0
  109. package/src/lib/services/global.service.spec.ts +801 -0
  110. package/src/lib/services/global.service.ts +724 -0
  111. package/src/lib/services/message.service.ts +556 -0
  112. package/src/lib/services/theme.service.ts +96 -0
  113. package/src/lib/template/authtemplate.component.html +6 -0
  114. package/src/lib/template/authtemplate.component.ts +13 -0
  115. package/src/lib/template/basetemplate.component.html +7 -0
  116. package/src/lib/template/basetemplate.component.ts +13 -0
  117. package/src/lib/template/index.ts +3 -0
  118. package/src/lib/template/modeltemplate.component.html +7 -0
  119. package/src/lib/template/modeltemplate.component.ts +21 -0
  120. package/src/lib/utils/piva.spec.ts +56 -0
  121. package/src/lib/utils/piva.ts +29 -0
  122. package/src/lib/validators/email.validator.spec.ts +57 -0
  123. package/src/lib/validators/email.validator.ts +17 -0
  124. package/src/lib/validators/equalPasswords.validator.spec.ts +54 -0
  125. package/src/lib/validators/equalPasswords.validator.ts +17 -0
  126. package/src/lib/validators/index.ts +2 -0
  127. package/src/lib/version.ts +1 -0
  128. package/src/public-api.ts +64 -0
  129. package/src/typings.d.ts +2 -0
  130. package/tsconfig.lib.json +18 -0
  131. package/tsconfig.lib.prod.json +9 -0
@@ -0,0 +1,747 @@
1
+ import {
2
+ Component,
3
+ ChangeDetectionStrategy,
4
+ OnDestroy,
5
+ inject,
6
+ DestroyRef,
7
+ signal,
8
+ computed,
9
+ input,
10
+ output,
11
+ effect,
12
+ } from '@angular/core';
13
+
14
+ import { GlobalService, Languages } from '../services/global.service';
15
+
16
+ import { AppMessageService } from '../services/message.service';
17
+
18
+ import { NgClass } from '@angular/common';
19
+
20
+ import {
21
+ ItemInterface,
22
+ Member,
23
+ TransportInterface,
24
+ FieldType,
25
+ ViewListInterface,
26
+ ManagmentInterface,
27
+ Entities,
28
+ EntitiesData,
29
+ } from '../interfaces/index';
30
+ import { ManagmentService } from '../home/model/services/index';
31
+ import { NEWPORT_CONFIG } from '../config';
32
+ import { AllCommunityModule, GridApi, GridOptions, ModuleRegistry } from 'ag-grid-community';
33
+ import { AgGridAngular } from 'ag-grid-angular';
34
+ import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
35
+ import { ThemeService } from '../services/theme.service';
36
+
37
+
38
+ @Component({
39
+ selector: 'grid',
40
+ templateUrl: 'grid.component.html',
41
+ imports: [AgGridAngular, NgClass],
42
+ changeDetection: ChangeDetectionStrategy.OnPush,
43
+ })
44
+ export class GridComponent implements OnDestroy {
45
+ gsv = inject(GlobalService);
46
+ msg = inject(AppMessageService);
47
+ msv = inject(ManagmentService);
48
+ private config = inject(NEWPORT_CONFIG);
49
+ themeService = inject(ThemeService);
50
+ private destroyRef = inject(DestroyRef);
51
+
52
+ readonly model = input<ItemInterface>();
53
+ readonly viewList = input<boolean>();
54
+ readonly lookup = input<string>('');
55
+ readonly filter = input<string>('');
56
+ readonly refreshGrid = input<boolean>();
57
+ readonly print = input<boolean>();
58
+
59
+ readonly viewChanged = output<ViewListInterface>();
60
+
61
+ public currentModel!: ItemInterface;
62
+ public selectedRows: any[] | null = null;
63
+ readonly currentTheme = this.themeService.currentTheme;
64
+ readonly loading = toSignal(this.gsv.getLoaderState(), {
65
+ initialValue: false,
66
+ });
67
+
68
+ readonly gridThemeClass = computed(() =>
69
+ this.currentTheme() === 'dark'
70
+ ? 'ag-theme-balham-dark grid-wrapper'
71
+ : 'ag-theme-balham grid-wrapper'
72
+ );
73
+
74
+ public fieldArray: string[] = [];
75
+ public fields!: Member[];
76
+ public managment: ManagmentInterface = {
77
+ functionId: '',
78
+ appId: '',
79
+ entId: '',
80
+ year: 0,
81
+ keys: '',
82
+ fields: [],
83
+ states: [],
84
+ entIds: [],
85
+ keyId: '1',
86
+ filterId: '',
87
+ page: 1,
88
+ data: '',
89
+ };
90
+ readonly columnDefs = signal<any>(null);
91
+ public rowData = signal<any[]>([]);
92
+ public gridOptions!: GridOptions;
93
+ public rowSelection = 'single';
94
+ public gridApi!: GridApi<any>;
95
+ public localeText!: any;
96
+ public defaultColDef!: any;
97
+ public title: string = '';
98
+
99
+ constructor() {
100
+ this.defaultColDef = {
101
+ sortable: true,
102
+ filter: true,
103
+ };
104
+ this.gridOptions = {
105
+ suppressNoRowsOverlay: true,
106
+ suppressLoadingOverlay: true,
107
+ };
108
+ this.localeText = this.msg.get('app.gridlocale');
109
+ ModuleRegistry.registerModules([AllCommunityModule]);
110
+
111
+ effect(
112
+ () => {
113
+ const m = this.model();
114
+ this.viewList();
115
+ this.lookup();
116
+ this.refreshGrid();
117
+ if (m) {
118
+ this.currentModel = m;
119
+ }
120
+ if (m || this.lookup()) {
121
+ this.changeData();
122
+ }
123
+ },
124
+ { allowSignalWrites: true }
125
+ );
126
+
127
+ effect(() => {
128
+ this.print();
129
+ if (this.gridApi && this.viewList()) {
130
+ this.exportToPDF(this.gridApi);
131
+ }
132
+ });
133
+ }
134
+
135
+ /** Clears all grid state (rows, columns, API references) to avoid memory leaks. */
136
+ public ngOnDestroy(): void {
137
+ this.rowData.set([]);
138
+ this.columnDefs.set([]);
139
+ this.fieldArray = [];
140
+ this.fields = [];
141
+ this.gridOptions = undefined!;
142
+ this.gridApi = undefined!;
143
+ }
144
+
145
+ /** Resolves managment IDs from the model or lookup input, then calls prepareData. */
146
+ public changeData() {
147
+ this.title =
148
+ this.gsv.getLng() === Languages.IT
149
+ ? this.currentModel?.title
150
+ : this.currentModel.titleGb;
151
+ if (
152
+ (this.currentModel && this.currentModel.name !== undefined) ||
153
+ this.lookup() !== ''
154
+ ) {
155
+ if (this.lookup() !== '') {
156
+ const lkinfo: string[] = this.lookup()!.split('#');
157
+ this.managment.appId = lkinfo[0].toUpperCase();
158
+ this.managment.year = parseInt(lkinfo[1], 10);
159
+ this.managment.entId = lkinfo[2].toUpperCase();
160
+ this.managment.keyId = '1';
161
+ this.managment.keys = 'prg=0';
162
+ const projectId = lkinfo[0].toUpperCase() + '.' + lkinfo[1];
163
+ const projectItems = this.gsv.getProjectItems(projectId);
164
+ if (projectItems === undefined) {
165
+ this.msv
166
+ .getItemsState(this.managment)
167
+ .pipe(takeUntilDestroyed(this.destroyRef))
168
+ .subscribe({
169
+ next: (data: ItemInterface[]) => {
170
+ this.gsv.setProjectItems(projectId, data);
171
+ this.prepareData();
172
+ },
173
+ error: () => {},
174
+ });
175
+ } else {
176
+ this.prepareData();
177
+ }
178
+ } else if (this.currentModel && this.currentModel.name !== undefined) {
179
+ this.managment.appId = this.gsv.getProject().project;
180
+ this.managment.year = this.gsv.getYear();
181
+ this.managment.entId = this.currentModel.name;
182
+ this.managment.keyId = this.gsv.getKeyId();
183
+ this.managment.keys = 'prg=0';
184
+ this.prepareData();
185
+ }
186
+ if (this.managment.appId === undefined) {
187
+ return;
188
+ }
189
+ }
190
+ }
191
+
192
+ /** Re-selects a previously selected row (by _prg) after the grid data refreshes. */
193
+ public selectRow(): void {
194
+ if (this.selectedRows !== null && this.selectedRows.length > 0) {
195
+ this.gridApi.deselectAll();
196
+ this.gridApi.forEachNodeAfterFilter(node => {
197
+ if (node.data._prg === this.selectedRows![0]._prg) {
198
+ node.setSelected(true);
199
+ }
200
+ });
201
+ this.selectedRows = null;
202
+ }
203
+ }
204
+
205
+ /** Loads project schema/data from cache or config and then calls setColumns + setData. */
206
+ public prepareData() {
207
+ if (
208
+ this.viewList() === true ||
209
+ (this.currentModel !== undefined &&
210
+ this.currentModel.masterDetail !== 0) ||
211
+ this.lookup() !== ''
212
+ ) {
213
+ this.gsv.setLoaderState(true);
214
+ this.config.projectsInfoLoader(this.managment.year, this.managment.appId)
215
+ .then(prj_Info => {
216
+ const id = this.managment.appId + '.' + this.managment.year;
217
+ if (!this.gsv.getDataJson(id)) {
218
+ this.gsv.setDataJson(id, prj_Info.getData());
219
+ }
220
+ if (!this.gsv.getSchemaJson(id)) {
221
+ this.gsv.setSchemaJson(id, prj_Info.getSchema());
222
+ }
223
+ let root: Entities | null = this.gsv.getSchemaJson(
224
+ this.managment.appId + '.' + this.managment.year
225
+ );
226
+ let entity = root?.entities.find(
227
+ e => e.name === this.managment.entId.toLocaleLowerCase()
228
+ );
229
+ if (entity) {
230
+ this.fields = entity.members;
231
+ this.setColumns(this.fields);
232
+ this.setData();
233
+ }
234
+ root = null;
235
+ entity = undefined;
236
+ })
237
+ .catch(() => this.gsv.setLoaderState(false));
238
+ }
239
+ }
240
+
241
+ /** Converts raw EntitiesData into a flat row array, resolving lookups and formatting values. */
242
+ public getData(data: EntitiesData): any[] | undefined {
243
+ if (!data || !this.fields) {
244
+ return undefined;
245
+ }
246
+ const module = data.entities.find(
247
+ e => e.name === this.managment.entId.toLocaleLowerCase()
248
+ );
249
+ if (!module) return undefined;
250
+ const rows: any[] = [];
251
+ for (const item of module.modules.filter(e => e.state === 1)) {
252
+ if (
253
+ item.members.length === 0 ||
254
+ item.state === 0 ||
255
+ (this.gsv.getCurrentLinkItem().id ===
256
+ this.managment.entId.toLocaleLowerCase() &&
257
+ this.gsv.getCurrentLinkItem().prg.length > 1 &&
258
+ this.gsv.getCurrentLinkItem().prg[0] !== item.prg[0])
259
+ ) {
260
+ continue;
261
+ }
262
+ const obj: { [k: string]: any } = {};
263
+ for (const member of item.members) {
264
+ obj['_prg'] = '';
265
+ for (let i = 0; i < item.prg.length; i++) {
266
+ if (obj['_prg'] !== '') {
267
+ obj['_prg'] += ',';
268
+ }
269
+ obj['_prg'] += item.prg[i];
270
+ }
271
+ if (this.fieldArray.lastIndexOf(member.name) !== -1) {
272
+ const value = member.value;
273
+ const field: Member | undefined = this.fields.find(
274
+ fld => fld.id === member.name
275
+ );
276
+ obj[member.name] = value ? value : null;
277
+ if (field && obj[member.name]) {
278
+ if (field.type === FieldType.Number) {
279
+ obj[member.name] =
280
+ this.gsv.getLng() === Languages.IT
281
+ ? parseFloat(obj[member.name]).toLocaleString('it-it', {
282
+ minimumFractionDigits: field.scale,
283
+ })
284
+ : parseFloat(obj[member.name]).toLocaleString('en-us', {
285
+ minimumFractionDigits: field.scale,
286
+ });
287
+ } else if (field.type === FieldType.Date) {
288
+ obj[member.name] = obj[member.name].toString();
289
+ }
290
+ }
291
+ if (field && field.lookup !== '' && field.lookuplink) {
292
+ const lkmanagment = this.gsv.getManagmentInterface();
293
+ const lkinfo: string[] = field.lookup.split('#');
294
+ const input: string[] = lkinfo[3].split(',');
295
+ const output: string[] = lkinfo[4].split(',');
296
+ lkmanagment.functionId = 'read';
297
+ lkmanagment.appId = lkinfo[0].toUpperCase();
298
+ lkmanagment.year = parseInt(lkinfo[1], 0);
299
+ lkmanagment.entId = lkinfo[2].toUpperCase();
300
+ if (
301
+ this.currentModel.groupName ===
302
+ this.gsv.getCurrentLinkItem().groupName &&
303
+ this.currentModel.prgDim > 1
304
+ ) {
305
+ lkmanagment.keys = 'prg=' + this.gsv.getCurrentLinkItem().prg[0];
306
+ } else {
307
+ lkmanagment.keys = 'prg=0';
308
+ }
309
+ const lkFieldsId: string =
310
+ lkmanagment.appId +
311
+ '.' +
312
+ lkmanagment.entId +
313
+ '.' +
314
+ lkmanagment.year;
315
+ const lkdata = this.gsv.getData(lkFieldsId);
316
+ if (!lkdata && !this.currentModel.cache) {
317
+ this.msv
318
+ .getData(lkmanagment)
319
+ .pipe(takeUntilDestroyed(this.destroyRef))
320
+ .subscribe(
321
+ (dtlk: TransportInterface) => {
322
+ this.gsv.setData(lkFieldsId, JSON.parse(dtlk.dataFile as string));
323
+ let val: any;
324
+ let elem: any;
325
+ switch (field.type) {
326
+ case 0:
327
+ val = value;
328
+ break;
329
+ case 1: {
330
+ const strValue = value as string;
331
+ if (field.thousandseparator) {
332
+ field.value =
333
+ this.gsv.getLng() === Languages.IT
334
+ ? parseFloat(
335
+ strValue.replace(',', '.')
336
+ ).toLocaleString('it-it', {
337
+ minimumFractionDigits: field.scale,
338
+ })
339
+ : parseFloat(strValue).toLocaleString('en-us', {
340
+ minimumFractionDigits: field.scale,
341
+ });
342
+ } else {
343
+ val = parseFloat(strValue).toLocaleString(
344
+ this.gsv.getLng() === Languages.IT
345
+ ? 'it-it'
346
+ : 'en-us',
347
+ { minimumFractionDigits: field.scale }
348
+ );
349
+ }
350
+ }
351
+ break;
352
+ }
353
+ elem = JSON.parse(dtlk.dataFile as string).find(
354
+ (e: any) => e[field.id] === val
355
+ );
356
+ if (elem !== undefined) {
357
+ for (let i = 0; i < input.length; i++) {
358
+ if (i > 0) {
359
+ obj[output[i]] = elem[input[i]];
360
+ }
361
+ }
362
+ }
363
+ },
364
+ error => {}
365
+ );
366
+ } else {
367
+ let val: any;
368
+ let elem: any;
369
+ switch (field.type) {
370
+ case 0:
371
+ val = value;
372
+ break;
373
+ case 1: {
374
+ const strValue = value as string;
375
+ if (field.thousandseparator) {
376
+ field.value =
377
+ this.gsv.getLng() === Languages.IT
378
+ ? parseFloat(strValue.replace(',', '.')).toLocaleString(
379
+ 'it-it',
380
+ { minimumFractionDigits: field.scale }
381
+ )
382
+ : parseFloat(strValue).toLocaleString('en-us', {
383
+ minimumFractionDigits: field.scale,
384
+ });
385
+ } else {
386
+ val = parseFloat(strValue).toLocaleString(
387
+ this.gsv.getLng() === Languages.IT ? 'it-it' : 'en-us',
388
+ { minimumFractionDigits: field.scale }
389
+ );
390
+ }
391
+ break;
392
+ }
393
+ }
394
+ // elem = lkdata.find((e) => e.fieldStates[id].value === val.toString());
395
+ elem = null;
396
+ if (elem !== undefined) {
397
+ for (let i = 0; i < input.length; i++) {
398
+ if (i > 0) {
399
+ obj[output[i]] = elem.fieldStates['_' + input[i]].value;
400
+ }
401
+ }
402
+ }
403
+ }
404
+ }
405
+ }
406
+ }
407
+ if (obj._prg !== '') {
408
+ rows.push(obj);
409
+ }
410
+ }
411
+ return rows;
412
+ }
413
+
414
+ /** Fetches entity data (from cache or API) and populates rowData via getData + filterData. */
415
+ public setData() {
416
+ if (!this.currentModel && this.lookup() !== '') {
417
+ const lkinfo: string[] = this.lookup()!.split('#');
418
+ this.currentModel = this.gsv
419
+ .getProjectItems(lkinfo[0].toUpperCase() + '.' + lkinfo[1])
420
+ .find(e => e.name === lkinfo[2].toUpperCase())!;
421
+ }
422
+ this.rowData.set([]);
423
+ this.managment.fields = [];
424
+ this.managment.functionId = 'read';
425
+ if (
426
+ this.currentModel.groupName === this.gsv.getCurrentLinkItem().groupName &&
427
+ this.currentModel.prgDim > 1
428
+ ) {
429
+ this.managment.keys = 'prg=' + this.gsv.getCurrentLinkItem().prg[0];
430
+ } else {
431
+ this.managment.keys = 'prg=0';
432
+ }
433
+ const lkFieldsId: string =
434
+ this.managment.appId +
435
+ '.' +
436
+ this.managment.entId +
437
+ '.' +
438
+ this.managment.year;
439
+ const lkdata = this.gsv.getData(lkFieldsId);
440
+ if (lkdata || this.currentModel.masterDetail != 0) {
441
+ this.rowData.set(this.filterData(this.getData(lkdata!) ?? []) ?? []);
442
+ this.gsv.setLoaderState(false);
443
+ } else {
444
+ this.msv
445
+ .getData(this.managment)
446
+ .pipe(takeUntilDestroyed(this.destroyRef))
447
+ .subscribe({
448
+ next: (data: TransportInterface) => {
449
+ this.gsv.setData(lkFieldsId, JSON.parse(data.dataFile as string));
450
+ this.rowData.set(
451
+ this.filterData(this.getData(JSON.parse(data.dataFile as string)) ?? []) ??
452
+ []
453
+ );
454
+ this.gsv.setLoaderState(false);
455
+ },
456
+ error: () => {},
457
+ });
458
+ }
459
+ }
460
+
461
+ /** Returns data filtered by the `filter` input expression (format: "field;value"). */
462
+ public filterData(data: any[]): any[] {
463
+ if (this.filter()) {
464
+ const fd: string[] = this.filter()!.split(',')[0].split(';');
465
+ return data.filter(e => e[fd[0]] === fd[1]);
466
+ }
467
+ return data;
468
+ }
469
+
470
+ /** Builds AG Grid column definitions from the entity schema members and preloads lookup data. */
471
+ public setColumns(fields: Member[]) {
472
+ const columns: any[] = [];
473
+ this.rowData.set([]);
474
+ this.columnDefs.set([]);
475
+ this.fieldArray = [];
476
+ columns.push({
477
+ headerName: '_prg',
478
+ field: '_prg',
479
+ width: 20,
480
+ hide: true,
481
+ });
482
+ this.fieldArray.push('_prg');
483
+ const sortedFields = this.gsv.sortArray(
484
+ 'viewlist',
485
+ this.fields.filter(item => item.viewlist > 0)
486
+ );
487
+ for (const field of sortedFields) {
488
+ if (field.type !== FieldType.Label && field.viewlist !== 0) {
489
+ this.fieldArray.push(field.name);
490
+ let width: number = 1.1 * parseFloat(field.width);
491
+ let widthName: number = 15.6 * field.name.length;
492
+ if (widthName < 100) {
493
+ widthName = 100;
494
+ }
495
+ if (field.caption === '' || field.width === '0px') {
496
+ widthName = 0;
497
+ width = 0;
498
+ }
499
+ columns.push({
500
+ headerName:
501
+ this.gsv.getLng() === Languages.IT
502
+ ? field.caption
503
+ : field.captiongb,
504
+ field: field.name,
505
+ width: Math.max(widthName, width),
506
+ minWidth: Math.max(widthName, width),
507
+ filter: true,
508
+ sortable: true,
509
+ suppressMenu: false,
510
+ floatingFilter: width !== 0,
511
+ cellStyle:
512
+ field.alignment === 'right'
513
+ ? { 'text-align': 'right' }
514
+ : field.alignment === 'center'
515
+ ? { 'text-align': 'center' }
516
+ : '',
517
+ headerClass:
518
+ field.alignment === 'right'
519
+ ? 'cellRight'
520
+ : field.alignment === 'center'
521
+ ? 'cellCenter'
522
+ : '',
523
+ });
524
+
525
+ if (field !== undefined && field.lookup !== '') {
526
+ const lkmanagment = this.gsv.getManagmentInterface();
527
+ const lkinfo: string[] = field.lookup.split('#');
528
+ const input: string[] = lkinfo[3].split(',');
529
+ const output: string[] = lkinfo[4].split(',');
530
+ lkmanagment.functionId = 'read';
531
+ lkmanagment.appId = lkinfo[0].toUpperCase();
532
+ lkmanagment.year = parseInt(lkinfo[1], 0);
533
+ lkmanagment.entId = lkinfo[2].toUpperCase();
534
+ lkmanagment.keys = 'prg=0';
535
+ const lkFieldsId: string =
536
+ lkmanagment.appId +
537
+ '.' +
538
+ lkmanagment.entId +
539
+ '.' +
540
+ lkmanagment.year;
541
+ const lkdata = this.gsv.getData(lkFieldsId);
542
+ if (!lkdata && this.currentModel && !this.currentModel.cache) {
543
+ this.msv
544
+ .getData(lkmanagment)
545
+ .pipe(takeUntilDestroyed(this.destroyRef))
546
+ .subscribe({
547
+ next: (dtlk: TransportInterface) => {
548
+ this.gsv.setData(lkFieldsId, JSON.parse(dtlk.dataFile as string));
549
+ },
550
+ error: () => {},
551
+ });
552
+ }
553
+ }
554
+ }
555
+ }
556
+ this.columnDefs.set(columns);
557
+ }
558
+
559
+ /** Stores the AG Grid API reference when the grid initialises. */
560
+ public onGridReady(params: any) {
561
+ this.gridApi = params.api;
562
+ }
563
+
564
+ /** Captures the clicked row and emits viewChanged to navigate to the record's detail view. */
565
+ public onRowClicked(event: any) {
566
+ if (event?.data) {
567
+ this.selectedRows = [event.data];
568
+ this.viewChanged.emit({
569
+ state: false,
570
+ rows: this.selectedRows,
571
+ });
572
+ }
573
+ }
574
+
575
+ /** Hook for row-data-changed events (currently unused). */
576
+ public onRowDataChanged(event: any) {}
577
+
578
+ /** Hook for filter-changed events (currently unused). */
579
+ public onFilterChanged(filter: any) {}
580
+
581
+ /**
582
+ * This function iterates over all of the columns to create a row of header cells
583
+ */
584
+ private getHeaderToExport = (gridApi: any) => {
585
+ if (gridApi) {
586
+ const columns = gridApi.getAllDisplayedColumns();
587
+ return columns.map((column: any) => {
588
+ const { field } = column.getColDef();
589
+ const sort = column.getSort();
590
+ // Enables export when row grouping
591
+ const headerName = column.getColDef().headerName ?? field;
592
+ const headerNameUppercase =
593
+ headerName[0].toUpperCase() + headerName.slice(1);
594
+ const headerCell = {
595
+ text: headerNameUppercase + (sort ? ` (${sort})` : ''),
596
+
597
+ // styles
598
+ bold: true,
599
+ margin: [0, 12, 0, 0],
600
+ };
601
+ return headerCell;
602
+ });
603
+ }
604
+ };
605
+
606
+ /**
607
+ * This function iterates over all of the rows and columns to create
608
+ * a matrix of cells when pivoting is enabled
609
+ */
610
+
611
+ private getRowsToExportPivot = (gridApi: any) => {
612
+ const rowsToExport: any[] = [];
613
+ if (gridApi) {
614
+ const columns = gridApi.getAllDisplayedColumns();
615
+ const getCellToExport = (column: any, node: any) => ({
616
+ text: gridApi.getValue(column, node) ?? '',
617
+ // styles
618
+ ...column.getColDef().cellStyle,
619
+ });
620
+ gridApi.forEachNodeAfterFilterAndSort((node: any) => {
621
+ if (node.group) {
622
+ const rowToExport = columns.map((column: any) =>
623
+ getCellToExport(column, node)
624
+ );
625
+ rowsToExport.push(rowToExport);
626
+ }
627
+ });
628
+ }
629
+ return rowsToExport;
630
+ };
631
+
632
+ /**
633
+ * This function iterates over all of the rows and columns to create
634
+ * a matrix of cells
635
+ */
636
+ private getRowsToExport = (gridApi: any) => {
637
+ const rowsToExport: any[] = [];
638
+ if (gridApi) {
639
+ //Enables export when pivoting
640
+ if (gridApi.isPivotMode()) {
641
+ return this.getRowsToExportPivot(gridApi);
642
+ }
643
+ const columns = gridApi.getAllDisplayedColumns();
644
+ const getCellToExport = (column: any, node: any) => ({
645
+ text: node.data[column.colId],
646
+ // styles
647
+ ...column.getColDef().cellStyle,
648
+ });
649
+ gridApi.forEachNodeAfterFilterAndSort((node: any) => {
650
+ const rowToExport = columns.map((column: any) =>
651
+ getCellToExport(column, node)
652
+ );
653
+ rowsToExport.push(rowToExport);
654
+ });
655
+ }
656
+ return rowsToExport;
657
+ };
658
+
659
+ // Row colors
660
+ private HEADER_ROW_COLOR = '#f8f8f8';
661
+ private EVEN_ROW_COLOR = '#fcfcfc';
662
+ private ODD_ROW_COLOR = '#fff';
663
+
664
+ private PDF_INNER_BORDER_COLOR = '#dde2eb';
665
+ private PDF_OUTER_BORDER_COLOR = '#babfc7';
666
+
667
+ private createLayout = (numberOfHeaderRows: any) => ({
668
+ fillColor: (rowIndex: any) => {
669
+ if (rowIndex < numberOfHeaderRows) {
670
+ return this.HEADER_ROW_COLOR;
671
+ }
672
+ return rowIndex % 2 === 0 ? this.EVEN_ROW_COLOR : this.ODD_ROW_COLOR;
673
+ },
674
+ //vLineHeight not used here.
675
+ vLineWidth: (rowIndex: any, node: any) =>
676
+ rowIndex === 0 || rowIndex === node.table.widths.length ? 1 : 0,
677
+ hLineColor: (rowIndex: any, node: any) =>
678
+ rowIndex === 0 || rowIndex === node.table.body.length
679
+ ? this.PDF_OUTER_BORDER_COLOR
680
+ : this.PDF_INNER_BORDER_COLOR,
681
+ vLineColor: (rowIndex: any, node: any) =>
682
+ rowIndex === 0 || rowIndex === node.table.widths.length
683
+ ? this.PDF_OUTER_BORDER_COLOR
684
+ : this.PDF_INNER_BORDER_COLOR,
685
+ });
686
+
687
+ /**
688
+ * Returns a pdfMake shaped config for export, for more information
689
+ * regarding pdfMake configuration, please see the pdfMake documentation.
690
+ */
691
+ private getDocument = (gridApi: any) => {
692
+ if (gridApi) {
693
+ const columns = gridApi.getAllDisplayedColumns();
694
+ const headerRow = this.getHeaderToExport(gridApi);
695
+ const rows = this.getRowsToExport(gridApi);
696
+ return {
697
+ pageOrientation: 'landscape', // can also be 'portrait'
698
+ content: [
699
+ this.title + '\n\n',
700
+ {
701
+ table: {
702
+ // the number of header rows
703
+ headerRows: 1,
704
+
705
+ // the width of each column, can be an array of widths
706
+ widths: `${100 / columns.length}%`,
707
+
708
+ // all the rows to display, including the header rows
709
+ body: [headerRow, ...rows],
710
+
711
+ // Header row is 40px, other rows are 15px
712
+ heights: (rowIndex: any) => (rowIndex === 0 ? 40 : 15),
713
+ },
714
+ layout: this.createLayout(1),
715
+ },
716
+ ],
717
+ pageMargins: [10, 10, 10, 10],
718
+ };
719
+ }
720
+ };
721
+
722
+ private exportToPDF = async (gridApi: GridApi) => {
723
+ if (gridApi) {
724
+ try {
725
+ const doc = this.getDocument(gridApi);
726
+ const date = new Date();
727
+ const [{ default: pdfMake }, { default: pdfFonts }] = await Promise.all([
728
+ import('pdfmake/build/pdfmake'),
729
+ import('pdfmake/build/vfs_fonts'),
730
+ ]);
731
+ pdfMake.vfs = (pdfFonts as any).pdfMake.vfs;
732
+ pdfMake
733
+ .createPdf(doc)
734
+ .download(
735
+ this.title +
736
+ '_' +
737
+ date.toDateString().trim() +
738
+ '_' +
739
+ date.toTimeString().trim() +
740
+ '.pdf'
741
+ );
742
+ } catch {
743
+ this.gsv.setLoaderState(false);
744
+ }
745
+ }
746
+ };
747
+ }