@unifylib/ui-lib 1.0.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 (129) hide show
  1. package/README.md +0 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +12 -0
  4. package/src/lib/base-model/SearchStrConfig.ts +12 -0
  5. package/src/lib/base-model/api-response.ts +23 -0
  6. package/src/lib/base-model/audit-log-entry.ts +7 -0
  7. package/src/lib/base-model/button-action-settings.ts +25 -0
  8. package/src/lib/base-model/column-def.model.ts +34 -0
  9. package/src/lib/base-model/do-action-request.ts +11 -0
  10. package/src/lib/base-model/field-action.ts +7 -0
  11. package/src/lib/base-model/field-filter.model.ts +14 -0
  12. package/src/lib/base-model/field-info.ts +98 -0
  13. package/src/lib/base-model/field-predicate.model.ts +7 -0
  14. package/src/lib/base-model/filter-request.ts +27 -0
  15. package/src/lib/base-model/filter.model.ts +49 -0
  16. package/src/lib/base-model/get-items-list.ts +24 -0
  17. package/src/lib/base-model/index.ts +11 -0
  18. package/src/lib/base-model/lookupItem.ts +21 -0
  19. package/src/lib/base-model/null-snackmessage.ts +9 -0
  20. package/src/lib/base-model/page-info.ts +51 -0
  21. package/src/lib/base-model/report-request.model.ts +33 -0
  22. package/src/lib/base-model/response-envelop.model.ts +15 -0
  23. package/src/lib/base-model/snack-message.model.ts +14 -0
  24. package/src/lib/base-model/snackmessage-interface.ts +7 -0
  25. package/src/lib/base-model/table-column.interface.ts +29 -0
  26. package/src/lib/base-model/table-page-user-action.interface.ts +33 -0
  27. package/src/lib/base-model/workflow/workflow-steps.model.ts +9 -0
  28. package/src/lib/base-model/workflow/workflow.model.ts +52 -0
  29. package/src/lib/components/action-confirmation/action-confirmation.component.css +34 -0
  30. package/src/lib/components/action-confirmation/action-confirmation.component.html +18 -0
  31. package/src/lib/components/action-confirmation/action-confirmation.component.spec.ts +23 -0
  32. package/src/lib/components/action-confirmation/action-confirmation.component.ts +58 -0
  33. package/src/lib/components/activity-report-form/activity-report-form.component.html +109 -0
  34. package/src/lib/components/activity-report-form/activity-report-form.component.scss +0 -0
  35. package/src/lib/components/activity-report-form/activity-report-form.component.spec.ts +25 -0
  36. package/src/lib/components/activity-report-form/activity-report-form.component.ts +605 -0
  37. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.css +51 -0
  38. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.html +23 -0
  39. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.spec.ts +23 -0
  40. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.ts +69 -0
  41. package/src/lib/components/audit-log-list/audit-log.component.html +23 -0
  42. package/src/lib/components/audit-log-list/audit-log.component.scss +0 -0
  43. package/src/lib/components/audit-log-list/audit-log.component.spec.ts +25 -0
  44. package/src/lib/components/audit-log-list/audit-log.component.ts +116 -0
  45. package/src/lib/components/auto-complete/auto-complete.component.css +14 -0
  46. package/src/lib/components/auto-complete/auto-complete.component.html +29 -0
  47. package/src/lib/components/auto-complete/auto-complete.component.spec.ts +23 -0
  48. package/src/lib/components/auto-complete/auto-complete.component.ts +330 -0
  49. package/src/lib/components/base-form/base-form.component.html +58 -0
  50. package/src/lib/components/base-form/base-form.component.scss +0 -0
  51. package/src/lib/components/base-form/base-form.component.spec.ts +25 -0
  52. package/src/lib/components/base-form/base-form.component.ts +305 -0
  53. package/src/lib/components/base-form-canvas/base-form-canvas.component.css +22 -0
  54. package/src/lib/components/base-form-canvas/base-form-canvas.component.html +1006 -0
  55. package/src/lib/components/base-form-canvas/base-form-canvas.component.spec.ts +23 -0
  56. package/src/lib/components/base-form-canvas/base-form-canvas.component.ts +573 -0
  57. package/src/lib/components/base-input-dialog/base-input-dialog.component.css +0 -0
  58. package/src/lib/components/base-input-dialog/base-input-dialog.component.html +42 -0
  59. package/src/lib/components/base-input-dialog/base-input-dialog.component.spec.ts +23 -0
  60. package/src/lib/components/base-input-dialog/base-input-dialog.component.ts +78 -0
  61. package/src/lib/components/base-table/base-table.component.html +242 -0
  62. package/src/lib/components/base-table/base-table.component.scss +31 -0
  63. package/src/lib/components/base-table/base-table.component.spec.ts +25 -0
  64. package/src/lib/components/base-table/base-table.component.ts +568 -0
  65. package/src/lib/components/button-actions/button-actions.component.html +28 -0
  66. package/src/lib/components/button-actions/button-actions.component.scss +6 -0
  67. package/src/lib/components/button-actions/button-actions.component.spec.ts +23 -0
  68. package/src/lib/components/button-actions/button-actions.component.ts +72 -0
  69. package/src/lib/components/editable-base-table/editable-base-table.component.html +372 -0
  70. package/src/lib/components/editable-base-table/editable-base-table.component.scss +44 -0
  71. package/src/lib/components/editable-base-table/editable-base-table.component.spec.ts +25 -0
  72. package/src/lib/components/editable-base-table/editable-base-table.component.ts +570 -0
  73. package/src/lib/components/equation-builder/equation-builder.component.css +0 -0
  74. package/src/lib/components/equation-builder/equation-builder.component.html +31 -0
  75. package/src/lib/components/equation-builder/equation-builder.component.spec.ts +23 -0
  76. package/src/lib/components/equation-builder/equation-builder.component.ts +121 -0
  77. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.css +11 -0
  78. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.html +38 -0
  79. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.spec.ts +23 -0
  80. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.ts +317 -0
  81. package/src/lib/components/paginator/paginator.component.css +25 -0
  82. package/src/lib/components/paginator/paginator.component.html +34 -0
  83. package/src/lib/components/paginator/paginator.component.ts +94 -0
  84. package/src/lib/components/rejection-comment/action-comment.component.css +33 -0
  85. package/src/lib/components/rejection-comment/action-comment.component.html +46 -0
  86. package/src/lib/components/rejection-comment/action-comment.component.spec.ts +23 -0
  87. package/src/lib/components/rejection-comment/action-comment.component.ts +86 -0
  88. package/src/lib/components/report-details-dialog/report-details-dialog.component.css +17 -0
  89. package/src/lib/components/report-details-dialog/report-details-dialog.component.html +16 -0
  90. package/src/lib/components/report-details-dialog/report-details-dialog.component.spec.ts +23 -0
  91. package/src/lib/components/report-details-dialog/report-details-dialog.component.ts +113 -0
  92. package/src/lib/components/report-form/report-form.component.html +94 -0
  93. package/src/lib/components/report-form/report-form.component.scss +0 -0
  94. package/src/lib/components/report-form/report-form.component.spec.ts +25 -0
  95. package/src/lib/components/report-form/report-form.component.ts +588 -0
  96. package/src/lib/components/search-bar/search-bar.component.html +62 -0
  97. package/src/lib/components/search-bar/search-bar.component.scss +8 -0
  98. package/src/lib/components/search-bar/search-bar.component.spec.ts +25 -0
  99. package/src/lib/components/search-bar/search-bar.component.ts +70 -0
  100. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.css +54 -0
  101. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.html +22 -0
  102. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.spec.ts +23 -0
  103. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.ts +45 -0
  104. package/src/lib/components/shared-list/shared-list.component.css +0 -0
  105. package/src/lib/components/shared-list/shared-list.component.html +17 -0
  106. package/src/lib/components/shared-list/shared-list.component.spec.ts +23 -0
  107. package/src/lib/components/shared-list/shared-list.component.ts +53 -0
  108. package/src/lib/components/title-bar/title-bar.component.css +0 -0
  109. package/src/lib/components/title-bar/title-bar.component.css.map +1 -0
  110. package/src/lib/components/title-bar/title-bar.component.html +31 -0
  111. package/src/lib/components/title-bar/title-bar.component.scss +23 -0
  112. package/src/lib/components/title-bar/title-bar.component.spec.ts +23 -0
  113. package/src/lib/components/title-bar/title-bar.component.ts +119 -0
  114. package/src/lib/services/backend-service.ts +286 -0
  115. package/src/lib/services/index.ts +3 -0
  116. package/src/lib/services/top-panel.ts +17 -0
  117. package/src/lib/services/trigger-form.service.ts +11 -0
  118. package/src/lib/share-module/shared-module.ts +10 -0
  119. package/src/lib/styles/invoiceq-theme.scss +252 -0
  120. package/src/lib/styles/styles.scss +1723 -0
  121. package/src/lib/utils/base-utils.ts +102 -0
  122. package/src/lib/validators/date-range-validator.ts +31 -0
  123. package/src/lib/validators/index.ts +3 -0
  124. package/src/lib/validators/match-list.validator.ts +10 -0
  125. package/src/lib/validators/multi-email-validator.ts +15 -0
  126. package/src/public-api.ts +21 -0
  127. package/tsconfig.lib.json +15 -0
  128. package/tsconfig.lib.prod.json +11 -0
  129. package/tsconfig.spec.json +15 -0
@@ -0,0 +1,568 @@
1
+ import {
2
+ ChangeDetectorRef,
3
+ Component,
4
+ effect,
5
+ EventEmitter,
6
+ Inject,
7
+ Input,
8
+ OnChanges, OnDestroy,
9
+ OnInit,
10
+ Output,
11
+ SimpleChanges
12
+ } from "@angular/core";
13
+ import {
14
+ MatCell,
15
+ MatCellDef,
16
+ MatColumnDef,
17
+ MatHeaderCell,
18
+ MatHeaderCellDef,
19
+ MatHeaderRow,
20
+ MatHeaderRowDef,
21
+ MatRow,
22
+ MatRowDef,
23
+ MatTable,
24
+ MatTableDataSource
25
+ } from "@angular/material/table";
26
+ import {TranslateModule, TranslateService} from "@ngx-translate/core";
27
+ import {MatSortModule} from "@angular/material/sort";
28
+ import {
29
+ CurrencyPipe,
30
+ DatePipe, DecimalPipe,
31
+ JsonPipe,
32
+ NgClass,
33
+ NgForOf,
34
+ NgIf,
35
+ NgStyle,
36
+ NgSwitch,
37
+ NgSwitchCase,
38
+ NgSwitchDefault
39
+ } from "@angular/common";
40
+ import {MatIcon} from "@angular/material/icon";
41
+ import {MatButton, MatButtonModule, MatIconButton} from "@angular/material/button";
42
+ import {NgxPaginationModule} from "ngx-pagination";
43
+ import {ButtonActionsComponent} from "../button-actions/button-actions.component";
44
+ import {ShareDataService} from "../../services/trigger-form.service";
45
+ import {BaseUtils} from "../../utils/base-utils";
46
+ import {BackendService} from "../../services/backend-service";
47
+ import {FlexLayoutModule} from "@angular/flex-layout";
48
+ import {Filter} from "../../base-model/filter.model";
49
+ import {FilterRequest} from "../../base-model/filter-request";
50
+ import {
51
+ ADD_NEW_RECORD_ACTION,
52
+ ButtonActionSettings,
53
+ EMPTY_PAGE_INFO,
54
+ FRONT_END_COLUMN_TYPES,
55
+ PageInfo,
56
+ SELECT_RECORD_ACTION, TABLE_RECORD_ACTION,
57
+ TableColumn
58
+ } from "../../base-model";
59
+ import {ReportRequest} from "../../base-model/report-request.model";
60
+ import {TablePageUserAction} from "../../base-model/table-page-user-action.interface";
61
+ import {Workflow} from "../../base-model/workflow/workflow.model";
62
+ import {ResponseEnvelop} from "../../base-model/response-envelop.model";
63
+ import {Router} from "@angular/router";
64
+ import {MatLabel} from "@angular/material/form-field";
65
+ import {MatChipListbox, MatChipOption} from "@angular/material/chips";
66
+ import {MatButtonToggle, MatButtonToggleGroup} from "@angular/material/button-toggle";
67
+ import {TitleBarComponent} from "../title-bar/title-bar.component";
68
+ import {PaginatorComponent} from "../paginator/paginator.component";
69
+ import {MatCheckbox} from "@angular/material/checkbox";
70
+
71
+ @Component({
72
+ selector: 'app-base-table',
73
+ standalone: true,
74
+ templateUrl: './base-table.component.html',
75
+ styleUrls: ['./base-table.component.scss'],
76
+ animations: [],
77
+ imports: [
78
+ NgStyle,
79
+ NgClass,
80
+ TranslateModule,
81
+ MatIcon,
82
+ MatSortModule,
83
+ MatColumnDef,
84
+ MatHeaderCellDef,
85
+ NgIf,
86
+ MatTable,
87
+ MatHeaderCell,
88
+ NgSwitch,
89
+ MatButtonModule,
90
+ MatCell,
91
+ MatCellDef,
92
+ DatePipe,
93
+ CurrencyPipe,
94
+ NgxPaginationModule,
95
+ MatRow,
96
+ MatRowDef,
97
+ MatHeaderRow,
98
+ NgSwitchCase,
99
+ NgSwitchDefault,
100
+ MatHeaderRowDef,
101
+ MatIconButton,
102
+ NgForOf,
103
+ JsonPipe,
104
+ FlexLayoutModule,
105
+ MatButton,
106
+ ButtonActionsComponent,
107
+ MatLabel,
108
+ MatChipListbox,
109
+ MatChipOption,
110
+ MatButtonToggleGroup,
111
+ MatButtonToggle,
112
+ TitleBarComponent,
113
+ PaginatorComponent,
114
+ DecimalPipe,
115
+ MatCheckbox,
116
+ ]
117
+ })
118
+ export class BaseTableComponent extends BaseUtils implements OnInit, OnChanges, OnDestroy {
119
+
120
+ collection = {count: 60, data: []};
121
+ config = {
122
+ itemsPerPage: 15,
123
+ currentPage: 1,
124
+ totalItems: this.collection.count
125
+ };
126
+ public maxSize: number = 7;
127
+ public directionLinks: boolean = true;
128
+ public autoHide: boolean = false;
129
+ public responsive: boolean = true;
130
+ public labels: any = {
131
+ previousLabel: '<',
132
+ nextLabel: '>',
133
+ screenReaderPaginationLabel: 'Pagination',
134
+ screenReaderPageLabel: 'page',
135
+ screenReaderCurrentLabel: `You're on page`
136
+ };
137
+
138
+ totalElements = 0;
139
+ pagesCount = 0;
140
+ pageIndex = 0;
141
+ private selectedStatusFilter: Filter[] = [];
142
+ advancedAppliedFilter: any[] = [];
143
+ searchStr: string = '';
144
+ private filterRequest: FilterRequest = new FilterRequest();
145
+ private timer: any;
146
+ @Input()
147
+ override pageInfo: PageInfo = EMPTY_PAGE_INFO;
148
+
149
+ @Input()
150
+ enablePagination: boolean = true;
151
+
152
+ @Input() data?: MatTableDataSource<any>;
153
+ @Input()
154
+ listAction: ButtonActionSettings[] = [];
155
+
156
+ @Input()
157
+ columns: TableColumn<any>[];
158
+
159
+ @Input()
160
+ filters: Filter[] = [];
161
+
162
+ @Input() //@ts-ignore
163
+ pathParam: number;
164
+
165
+ @Input() //@ts-ignore
166
+ extraButton: string;
167
+
168
+ @Input() //@ts-ignore
169
+ enforceRefresh: boolean = false;
170
+
171
+ @Input()
172
+ isPending: boolean = false;
173
+
174
+ @Input()
175
+ trigger: boolean = false;
176
+
177
+ @Input()
178
+ reportRequest: ReportRequest = new ReportRequest({});
179
+
180
+ @Input()
181
+ separateEndpointData: any;
182
+ @Input()
183
+ manageablePages: boolean = false;
184
+ @Input()
185
+ totalPagesCount: number = 0;
186
+ @Input()
187
+ currentPageIndex: number = 0;
188
+
189
+ @Output()
190
+ pageChange: EventEmitter<any> = new EventEmitter();
191
+
192
+
193
+ @Output()
194
+ userAction: EventEmitter<TablePageUserAction> = new EventEmitter<TablePageUserAction>();
195
+ @Output()
196
+ hyperLinkAction: EventEmitter<TablePageUserAction> = new EventEmitter<TablePageUserAction>();
197
+
198
+ @Output()
199
+ extraAction: EventEmitter<TablePageUserAction> = new EventEmitter<TablePageUserAction>();
200
+
201
+ @Output()
202
+ listActionClicked: EventEmitter<{ action: ButtonActionSettings, row: any }> = new EventEmitter<{
203
+ action: ButtonActionSettings,
204
+ row: any
205
+ }>();
206
+
207
+ @Output()
208
+ showDialog: EventEmitter<any> = new EventEmitter<any>();
209
+
210
+ usedWorkflow!: Workflow;
211
+
212
+ mode:any;
213
+
214
+ @Input()
215
+ customizedData?: MatTableDataSource<any>;
216
+ dataSource: MatTableDataSource<any>;
217
+ selectedRowIndex = -1;
218
+ noDataFound = false;
219
+ totalRequiredCountItem = 0;
220
+
221
+
222
+
223
+ @Output()
224
+ clickRoutePage: EventEmitter<any> = new EventEmitter<any>();
225
+
226
+ constructor(
227
+ private backendService: BackendService,
228
+ public translateService: TranslateService,
229
+ public shareDataService: ShareDataService,
230
+ @Inject('securityManager') private securityManager: any,
231
+ private router: Router,
232
+ ) {
233
+ super();
234
+ this.dataSource = new MatTableDataSource();
235
+ this.columns = [];
236
+ this.filterRequest = new FilterRequest();
237
+
238
+ effect(() => {
239
+ if (this.pageInfo.lazyLoadData !== true || this.enforceRefresh === true) {
240
+ this.loadData();
241
+ }
242
+ });
243
+
244
+ }
245
+
246
+ ngOnDestroy(): void {
247
+ console.log('Component Destroyed ');
248
+ }
249
+
250
+ ngOnInit(): void {
251
+ this.backendService.isEmptyItems = this.dataSource.data.length <= 0;
252
+ if (this.customizedData) {
253
+ this.dataSource = this.customizedData;
254
+ }
255
+ if(this.manageablePages) {
256
+ this.pagesCount = this.totalPagesCount;
257
+ this.pageIndex = this.currentPageIndex;
258
+ }
259
+ console.log(`${this.customizedData?.data},${this.dataSource.data?.length > 0} && ${!this.pageInfo.hidePagination} from Down ***** manage ${this.manageablePages}, page Count ${this.pagesCount}, page Index ${this.pageIndex}, ${this.totalPagesCount},${this.currentPageIndex}`);
260
+
261
+ }
262
+
263
+ onPageChange(event: number) {
264
+ this.getNext(event - 1);
265
+ if(this.manageablePages){
266
+ this.pageChange.emit(event);
267
+ }else {
268
+ this.getNext(event - 1);
269
+ }
270
+ this.config.currentPage = event;
271
+ }
272
+
273
+ extractFieldName(element: any, property: string) {
274
+ if (property.includes('.')) {
275
+ return property.split('.').reduce((acc, part) => acc && acc[part], element);
276
+ } else {
277
+ const c = this.columns.find(c => c.property === property);
278
+ if (Array.isArray(element[property]) && c.arraySubProperty ) {
279
+ const fieldValues = element[property].map(f => f[c.arraySubProperty]);
280
+ return fieldValues.join(', ');
281
+ }else {
282
+ return element[property];
283
+ }
284
+ }
285
+ }
286
+
287
+ get visibleColumns() {
288
+ this.buildGroups()
289
+ return this.columns.filter(column => column.visible).map(column => column.property);
290
+ }
291
+
292
+ getNext($event: number) {
293
+ this.reportRequest.filterRequest.pageIndex = $event;
294
+ this.loadData()
295
+ }
296
+
297
+ private loadData() {
298
+ clearTimeout(this.timer);
299
+ if (!this.reportRequest.filterRequest) {
300
+ this.reportRequest.filterRequest = new FilterRequest(this.pageInfo.pageSize);
301
+ this.reportRequest.filterRequest.filters = [];
302
+ }
303
+ if (this.separateEndpointData || !this.pageInfo.apiUri || this.pageInfo.apiUri.length === 0) {
304
+ this.dataSource.data = this.separateEndpointData;
305
+ } else if(this.reportRequest == undefined){
306
+ return;
307
+ } else if(!this.manageablePages) {
308
+ this.timer = setTimeout(() => {
309
+ this.reportRequest.filterRequest.columns = this.columns?.filter(c => FRONT_END_COLUMN_TYPES.indexOf(c.type) < 0 ).map(c => c.property) || [];
310
+ this.reportRequest.filterRequest.pendingPage = this.isPending;
311
+ if (this.filters?.length>0) {
312
+ this.reportRequest.filterRequest.filters = this.reportRequest.filterRequest.filters.concat(this.filters);
313
+ }
314
+ this.backendService.getItemsByFilter(this.reportRequest?.filterRequest, this.pageInfo.apiUri).subscribe(resp => {
315
+ const responseEnvelope = new ResponseEnvelop(resp);
316
+ if (responseEnvelope.valid) {
317
+ this.totalRequiredCountItem = this.reportRequest.filterRequest.pageSize
318
+ this.noDataFound = responseEnvelope.body.length < 1;
319
+ this.dataSource.data = responseEnvelope.body;
320
+ this.backendService.isEmptyItems = this.dataSource.data.length <= 0;
321
+ this.totalElements = responseEnvelope.totalSize || 0;
322
+ this.pagesCount = responseEnvelope.pagesCount || 1;
323
+ this.pageIndex = this.reportRequest.filterRequest.pageIndex + 1;
324
+ this.config.totalItems = responseEnvelope.totalSize || 0;
325
+ this.config.currentPage = this.pageIndex + 1;
326
+ // this.pageSize = this.reportRequest.filterRequest.pageSize;
327
+ }
328
+ });
329
+ }
330
+ , 300);
331
+ }
332
+ }
333
+
334
+ getStatusDescription(element: any) {
335
+ return this.backendService.getStatusDescription(element, this.usedWorkflow);
336
+ }
337
+
338
+ getStateType(element: any) {
339
+ return element.stateType
340
+ }
341
+
342
+ ngOnChanges(changes: SimpleChanges): void {
343
+ if (changes["customizedData"] && !changes["customizedData"].isFirstChange()) {
344
+ this.dataSource.data = changes["customizedData"].currentValue?.data || []; // Update data source with new data
345
+ this.pagesCount=this.totalPagesCount;
346
+ this.pageIndex=this.currentPageIndex;
347
+ }
348
+ if (changes["enforceRefresh"] && !changes["enforceRefresh"].isFirstChange()) {
349
+ this.loadData();
350
+ }
351
+ }
352
+ getCroppedText(elementValue: any, subWidth: number = 20) {
353
+ return elementValue && elementValue.length > subWidth ? elementValue.substring(0, subWidth) + "..." : elementValue;
354
+ }
355
+
356
+ emitEvent(element: any) {
357
+ this.showDialog.emit(element);
358
+ }
359
+
360
+ extractFormat(column: TableColumn<any>) {
361
+ return column?.format || 'd/M/yyyy, h:mm a';
362
+ }
363
+
364
+ actionListClicked(listAction: ButtonActionSettings, element: any) {
365
+ this.listActionClicked.emit({action:listAction, row: element});
366
+ }
367
+
368
+ hyperLinkClicked(actionName: string, element: any) {
369
+ const action = TABLE_RECORD_ACTION;
370
+ action.actionKey = actionName;
371
+ action.item = element;
372
+ action.pageInfo = this.pageInfo;
373
+ this.hyperLinkAction.emit(action)
374
+ }
375
+
376
+
377
+ emitRoutePage(element: any){
378
+ this.clickRoutePage.emit(element);
379
+ }
380
+
381
+ onSelectItem(row: any) {
382
+ // console.log('row', row)
383
+ if (this.pageInfo.selfRouting) {
384
+ const mode = this.isPending ? 'pending' : 'view';
385
+ const url = `${this.pageInfo.listRoutePath || this.router.url}/view`;
386
+ const encryptedId = this.backendService.encrypt(row.id+"");
387
+ const encryptedMode = this.backendService.encrypt(mode);
388
+ this.router.navigate([`${url}`],
389
+ { queryParams: { token: encryptedId , mode : encryptedMode } });
390
+ return;
391
+ }
392
+ // const action = SELECT_RECORD_ACTION;
393
+ // action.id = row?.id;
394
+ // action.item = row;
395
+ // this.userAction.emit(action)
396
+ }
397
+
398
+ openNewTab(row) {
399
+ if (!this.pageInfo.embededTableOnly) {
400
+ const mode = this.isPending ? 'pending' : 'view';
401
+ window.open(`${this.pageInfo.listRoutePath}/${mode}` + '/' + row?.id);
402
+ }
403
+ }
404
+
405
+ switchViewMode(b: boolean) {
406
+ this.isPending = !this.isPending;
407
+ this.loadData();
408
+ }
409
+
410
+ onAddNewAction($event: any) {
411
+ const url = `${this.pageInfo.listRoutePath || this.router.url}/view`;
412
+ const encryptedId = this.backendService.encrypt("-1");
413
+ const encryptedMode = this.backendService.encrypt("pending");
414
+ this.router.navigate([`${url}`],
415
+ { queryParams: { token: encryptedId , mode : encryptedMode } });
416
+
417
+ // const action = SELECT_RECORD_ACTION;
418
+ // action.id = row?.id;
419
+ // action.item = row;
420
+ // this.userAction.emit(action)
421
+ }
422
+
423
+ showAddNew() {
424
+ return this.pageInfo.hasAddButton ;
425
+ }
426
+
427
+ onExtraButtionAction($event: any) {
428
+ this.extraAction.emit($event);
429
+
430
+ }
431
+
432
+ hasGroups() {
433
+ let b = this.columns.findIndex(p => p.group);
434
+ return b >= 0;
435
+ }
436
+ groupNames: any = []
437
+ groupSpans: Map<string, number> = new Map();
438
+
439
+ buildGroups(){
440
+ let count = 0;
441
+ this.groupNames = [];
442
+ this.groupSpans.clear();
443
+ if(this.hasGroups() === false){
444
+ return;
445
+ }
446
+ this.columns
447
+ .filter(column => column.visible === true)
448
+ .forEach((column) => {
449
+ if (column.group === "-") {
450
+ this.groupNames.push(count.toString());
451
+ this.insertInMap(count);
452
+ count++;
453
+ return;
454
+ } else if (!this.groupNames.includes(column.group)) {
455
+ this.groupNames.push(column.group);
456
+ this.insertInMap(column.group);
457
+ return;
458
+ }
459
+ this.insertInMap(column.group);
460
+ });
461
+ }
462
+
463
+ insertInMap(key){
464
+ if(this.groupSpans.has(key)){
465
+ this.groupSpans.set(key.toString(), this.groupSpans.get(key) + 1);
466
+ } else {
467
+ this.groupSpans.set(key.toString(), 1);
468
+ }
469
+ }
470
+
471
+ isHumanMade(str){
472
+ return isNaN(str);
473
+ }
474
+
475
+ actionButtonClicked(actionKey: string, item: any): void {
476
+ if (actionKey === 'navigate') {
477
+ this.handleNavigateAction(item);
478
+ return;
479
+ }
480
+
481
+ this.emitTableAction(actionKey, item);
482
+ }
483
+
484
+ private handleNavigateAction(item: any): void {
485
+ const mode = this.isPending ? 'pending' : 'view';
486
+ const basePath = this.pageInfo.listRoutePath || this.router.url;
487
+ const url = `${basePath}/view`;
488
+
489
+ const encryptedId = this.backendService.encrypt(item.id.toString());
490
+ const encryptedMode = this.backendService.encrypt(mode);
491
+
492
+ this.router.navigate([url], {
493
+ queryParams: { token: encryptedId, mode: encryptedMode }
494
+ });
495
+ }
496
+
497
+ private emitTableAction(actionKey: string, item: any): void {
498
+ const action = TABLE_RECORD_ACTION;
499
+ action.actionKey = actionKey;
500
+ action.item = item;
501
+ action.pageInfo = this.pageInfo;
502
+ this.userAction.emit(action);
503
+ }
504
+
505
+ extractReport(reportType: any) {
506
+ const myFilters = this.reportRequest.filterRequest;
507
+ const reportRequest = this.backendService.buildReportRequest(this.columns, this.pageInfo.labelsSection + '.list_title',
508
+ myFilters, reportType, this.pageInfo, this.searchStr, 'LANDSCAPE');
509
+ this.backendService.downloadReport(reportRequest, this.pageInfo.apiUri);
510
+ }
511
+
512
+ getIcon(status: string): string {
513
+ switch (status) {
514
+ case 'pass': return 'check_circle';
515
+ case 'warning': return 'warning';
516
+ case 'error': return 'error';
517
+ default: return 'help';
518
+ }
519
+ }
520
+
521
+ actionCheckedClicked(property: string, element) {
522
+ element[property]= !element[property];
523
+ this.actionButtonClicked(property, element);
524
+ }
525
+
526
+
527
+ isDarkHighlight(row: any): boolean {
528
+ const groupByProp = this.pageInfo?.groupByProperty;
529
+ const groupByValues = this.pageInfo?.groupByValue;
530
+
531
+ if (!groupByProp || !groupByValues || !row[groupByProp]) {
532
+ return false;
533
+ }
534
+
535
+ const cellValue = row[groupByProp].toString();
536
+
537
+ return groupByValues.some(val =>
538
+ cellValue.includes(val) && cellValue.length > val.length
539
+ );
540
+ }
541
+
542
+ shouldRenderAsHyperLink(element: any): boolean {
543
+ const groupByProp = this.pageInfo?.groupByProperty;
544
+ const groupByValues = this.pageInfo?.groupByValue;
545
+
546
+ if (!groupByProp || !groupByValues || !element[groupByProp]) {
547
+ return false;
548
+ }
549
+
550
+ const value = element[groupByProp].toString();
551
+
552
+ return !groupByValues.some(v => value.includes(v) && value.length >= v.length);
553
+ }
554
+
555
+ shouldShowButton(element: any): boolean {
556
+ const groupByProp = this.pageInfo?.groupByProperty;
557
+ const groupByValues = this.pageInfo?.groupByValue;
558
+
559
+ if (!groupByProp || !groupByValues || !element[groupByProp]) {
560
+ return true;
561
+ }
562
+
563
+ const value = element[groupByProp].toString();
564
+
565
+ return !groupByValues.some(v => value.includes(v) && value.length >= v.length);
566
+ }
567
+
568
+ }
@@ -0,0 +1,28 @@
1
+ <ng-container *ngIf="buttonsAction; else list_Action">
2
+ <div fxLayout="row" fxLayoutAlign="start start" style="padding: 0 10px">
3
+ <div fxLayout="column" *ngFor="let action of actions; let i = index" style="padding: 0 10px">
4
+ <button [ngClass]="action.isPrimary ? 'btn-background-primary' : 'btn-none-background-primary'"
5
+ (click)="getClickedAction(action)"
6
+ [style]="'width: auto;border: var(--primary-color-2nd) solid 1px;cursor: pointer'"
7
+ class="icon-design"
8
+ [disabled]="disabled"
9
+ >
10
+ {{ action.label | translate}}
11
+ <mat-icon *ngIf="action.icon?.length" svgIcon={{action.icon}} class="svgColor"></mat-icon>
12
+ </button>
13
+ </div>
14
+ </div>
15
+ </ng-container>
16
+
17
+ <ng-template #list_Action>
18
+ <div *ngIf="listAction?.length > 0">
19
+ <button mat-icon-button [matMenuTriggerFor]="menu" (click)="$event.stopPropagation()" style="justify-content: center; color: grey">
20
+ <mat-icon>more_vert</mat-icon>
21
+ </button>
22
+ <mat-menu #menu="matMenu">
23
+ <button mat-menu-item *ngFor="let list_Action of listAction" (click)="getClickedAction(list_Action)">
24
+ <span>{{list_Action.label}}</span>
25
+ </button>
26
+ </mat-menu>
27
+ </div>
28
+ </ng-template>
@@ -0,0 +1,6 @@
1
+
2
+ .svgColor{
3
+ fill: transparent !important;
4
+ stroke: var(--accent-color) !important;
5
+
6
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ButtonActionsComponent } from './button-actions.component';
4
+
5
+ describe('ButtonActionsComponent', () => {
6
+ let component: ButtonActionsComponent;
7
+ let fixture: ComponentFixture<ButtonActionsComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ButtonActionsComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(ButtonActionsComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,72 @@
1
+ import {Component, EventEmitter, Input, Output} from '@angular/core';
2
+ import {ButtonActionSettings} from "../../base-model/button-action-settings";
3
+ import {MatDialog} from "@angular/material/dialog";
4
+ import {ActionCommentComponent} from "../rejection-comment/action-comment.component";
5
+ import {MatIcon} from "@angular/material/icon";
6
+ import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu";
7
+ import {MatIconButton} from "@angular/material/button";
8
+ import {NgClass, NgForOf, NgIf} from "@angular/common";
9
+ import {TranslateModule} from "@ngx-translate/core";
10
+ import {FlexModule} from "@angular/flex-layout";
11
+
12
+ @Component({
13
+ selector: 'app-button-actions',
14
+ standalone: true,
15
+ imports: [
16
+ MatIcon,
17
+ MatMenuTrigger,
18
+ MatIconButton,
19
+ MatMenu,
20
+ MatMenuItem,
21
+ NgIf,
22
+ NgClass,
23
+ FlexModule,
24
+ NgForOf,
25
+ TranslateModule
26
+ ],
27
+ templateUrl: './button-actions.component.html',
28
+ styleUrl: './button-actions.component.scss'
29
+ })
30
+ export class ButtonActionsComponent {
31
+ constructor(public dialog: MatDialog) { }
32
+
33
+ @Input()
34
+ actions: ButtonActionSettings[] =[];
35
+ @Input()
36
+ disabled?: boolean = false;
37
+
38
+ @Output()
39
+ clickedButton: EventEmitter<any> = new EventEmitter();
40
+
41
+ @Input()
42
+ buttonsAction: boolean = false;
43
+
44
+ @Input()
45
+ listAction: ButtonActionSettings[] = [];
46
+ ngOnInit(): void {
47
+ }
48
+
49
+
50
+ getClickedAction(action: ButtonActionSettings) {
51
+ if (action.showCommentDialog === true) {
52
+ const dialogRef = this.dialog.open(ActionCommentComponent, {
53
+ data: {label: action.label, isTermination: action.commentRequired, external: false,
54
+ warningMsg: false},
55
+ width: '600px',
56
+ height: 'auto',
57
+ direction: 'ltr' // this.authService.dir === 'rtl' ? 'rtl': 'ltr'
58
+ });
59
+ dialogRef.afterClosed().subscribe(result => {
60
+ if (result) {
61
+ action.comment = result.comment;
62
+ action.shareExternal = result.shareExternal;
63
+ this.clickedButton.emit(action);
64
+ }
65
+ });
66
+
67
+ } else {
68
+ this.clickedButton.emit(action);
69
+ }
70
+ }
71
+
72
+ }