@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,570 @@
1
+ import {
2
+ Component,
3
+ ElementRef,
4
+ EventEmitter,
5
+ Input,
6
+ OnChanges,
7
+ OnInit,
8
+ Output,
9
+ SimpleChanges,
10
+ ViewChild
11
+ } from "@angular/core";
12
+ import {
13
+ MatCell,
14
+ MatCellDef,
15
+ MatColumnDef,
16
+ MatHeaderCell,
17
+ MatHeaderCellDef,
18
+ MatHeaderRow,
19
+ MatHeaderRowDef,
20
+ MatRow,
21
+ MatRowDef,
22
+ MatTable
23
+ } from "@angular/material/table";
24
+ import {TranslateModule} from "@ngx-translate/core";
25
+ import {MatSortModule} from "@angular/material/sort";
26
+ import {NgClass, NgForOf, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault} from "@angular/common";
27
+ import {MatIcon} from "@angular/material/icon";
28
+ import {MatButton, MatButtonModule} from "@angular/material/button";
29
+ import {NgxPaginationModule} from "ngx-pagination";
30
+ import {FlexLayoutModule} from "@angular/flex-layout";
31
+ import {Router} from "@angular/router";
32
+ import {AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms";
33
+ import {MatError, MatFormField, MatInput, MatLabel, MatSuffix} from "@angular/material/input";
34
+ import {BackendService} from "../../services";
35
+ import {
36
+ BaseUtils,
37
+ buildFormFields,
38
+ getNegativeWfActionKey,
39
+ getPositiveWfActionKey,
40
+ getWfActionId
41
+ } from "../../utils/base-utils";
42
+ import {
43
+ EMPTY_PAGE_INFO,
44
+ FieldInfo,
45
+ Filter,
46
+ FilterRequest,
47
+ LookupItem,
48
+ PageInfo,
49
+ SELECT_RECORD_ACTION,
50
+ SnackMessage,
51
+ TableColumn
52
+ } from "../../base-model";
53
+ import {DoActionRequest, REJECT, SAVE} from "../../base-model/do-action-request";
54
+ import {ActionCommentComponent} from "../rejection-comment/action-comment.component";
55
+ import {MatDialog} from "@angular/material/dialog";
56
+ import {MatDatepicker, MatDatepickerInput, MatDatepickerToggle} from "@angular/material/datepicker";
57
+ import moment, {Moment} from 'moment';
58
+ import {AutoCompleteComponent} from "../auto-complete/auto-complete.component";
59
+ import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatOption} from "@angular/material/core";
60
+ import {MatChipListbox, MatChipOption} from "@angular/material/chips";
61
+ import {TitleBarComponent} from "../title-bar/title-bar.component";
62
+ import {PaginatorComponent} from "../paginator/paginator.component";
63
+ import {Directionality} from "@angular/cdk/bidi";
64
+ import {AttachmentUploaderComponent} from "../shared/attachment-uploader/attachment-uploader.component";
65
+ import {EquationBuilderComponent} from "../equation-builder/equation-builder.component";
66
+ import {MatSelect} from "@angular/material/select";
67
+
68
+ import {BaseFormCanvasComponent} from "../base-form-canvas/base-form-canvas.component";
69
+ import {MatCheckbox} from "@angular/material/checkbox";
70
+ @Component({
71
+ selector: 'app-editable-base-table',
72
+ standalone: true,
73
+ templateUrl: './editable-base-table.component.html',
74
+ styleUrls: ['./editable-base-table.component.scss'],
75
+ animations: [],
76
+ imports: [
77
+ NgClass,
78
+ TranslateModule,
79
+ MatIcon,
80
+ MatSortModule,
81
+ MatColumnDef,
82
+ MatHeaderCellDef,
83
+ NgIf,
84
+ MatTable,
85
+ MatHeaderCell,
86
+ NgSwitch,
87
+ MatButtonModule,
88
+ MatCell,
89
+ MatCellDef,
90
+ NgxPaginationModule,
91
+ MatRow,
92
+ MatRowDef,
93
+ MatHeaderRow,
94
+ NgSwitchCase,
95
+ NgSwitchDefault,
96
+ MatHeaderRowDef,
97
+ NgForOf,
98
+ FlexLayoutModule,
99
+ MatButton,
100
+ ReactiveFormsModule,
101
+ MatInput,
102
+ AutoCompleteComponent,
103
+ MatFormField,
104
+ MatDatepicker,
105
+ MatDatepickerInput,
106
+ MatDatepickerToggle,
107
+ MatLabel,
108
+ MatSuffix,
109
+ MatChipListbox,
110
+ MatChipOption,
111
+ TitleBarComponent,
112
+ PaginatorComponent,
113
+ AttachmentUploaderComponent,
114
+ EquationBuilderComponent,
115
+ MatSelect,
116
+ MatOption,
117
+ BaseFormCanvasComponent,
118
+ MatCheckbox,
119
+ ],
120
+ providers: [
121
+ // `MomentDateAdapter` can be automatically provided by importing `MomentDateModule` in your
122
+ // application's root module. We provide it at the component level here, due to limitations of
123
+ // our example generation script.
124
+ // {
125
+ // provide: DateAdapter,
126
+ // useClass: MomentDateAdapter,
127
+ // deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
128
+ // },
129
+
130
+ // { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
131
+ ],
132
+ })
133
+
134
+ export class EditableBaseTableComponent extends BaseUtils implements OnInit, OnChanges {
135
+
136
+ collection = {count: 60, data: []};
137
+ config = {
138
+ itemsPerPage: 10,
139
+ currentPage: 1,
140
+ totalItems: this.collection.count
141
+ };
142
+ public maxSize: number = 7;
143
+ public directionLinks: boolean = true;
144
+ public autoHide: boolean = false;
145
+ public responsive: boolean = true;
146
+ public labels: any = {
147
+ previousLabel: '<',
148
+ nextLabel: '>',
149
+ screenReaderPaginationLabel: 'Pagination',
150
+ screenReaderPageLabel: 'page',
151
+ screenReaderCurrentLabel: `You're on page`
152
+ };
153
+
154
+ private timer: any;
155
+ dataElements: any[] = [];
156
+ noDataFound = false;
157
+ isLoaded: boolean = false;
158
+ totalElements = 0;
159
+ pagesCount = 0;
160
+ pageIndex = 0;
161
+ formParam: FormGroup;
162
+ searchForm: FormGroup;
163
+
164
+ @Input()
165
+ filterRequest: FilterRequest;
166
+
167
+ @Input()
168
+ superDataElements: any[];
169
+
170
+ @Input()
171
+ override pageInfo: PageInfo = EMPTY_PAGE_INFO;
172
+
173
+ @Input() //@ts-ignore
174
+ enforceRefresh: boolean = false;
175
+
176
+ @Input()
177
+ isPending: boolean = false;
178
+
179
+ @Input()
180
+ isBulkItemsSupported: boolean = false;
181
+
182
+ @Input()// @ts-ignore
183
+ public fields: FieldInfo[] = [];
184
+
185
+ @Input()// @ts-ignore
186
+ public searchFormFields: FieldInfo[] = [];
187
+
188
+ @Input() translationKey: string = 'addNew';
189
+
190
+ @Output()
191
+ formUpdated: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
192
+
193
+ @Output()
194
+ saveActionEmitter: EventEmitter<any> = new EventEmitter<any>();
195
+ @Output()
196
+ saveAttachmentEmitter: EventEmitter<any> = new EventEmitter<any>();
197
+
198
+ @Input() actionRequestCallback!: (actionRequest: DoActionRequest) => DoActionRequest;
199
+
200
+ @ViewChild('uploader') uploaderComponent!: AttachmentUploaderComponent;
201
+
202
+ currentDirection: 'ltr' | 'rtl';
203
+ selectedFileFromUploader: File | null = null;
204
+ private selectedItem: any;
205
+
206
+
207
+ constructor(
208
+ private backendService: BackendService,
209
+ private router: Router,
210
+ private fb: FormBuilder,
211
+ public dialog: MatDialog,
212
+ private directionality: Directionality
213
+ ) {
214
+ super();
215
+ }
216
+
217
+ get dataFormArray(): FormArray {
218
+ return this.formParam.get('dataFormArray') as FormArray;
219
+ }
220
+
221
+ extractFormat(column: TableColumn<any>) {
222
+ return column?.format || 'd/M/yyyy, h:mm a';
223
+ }
224
+
225
+ get dataSource() {
226
+ return this.dataFormArray.value;
227
+ }
228
+
229
+ ngOnInit(): void {
230
+
231
+ this.currentDirection = this.directionality.value;
232
+ this.directionality.change.subscribe((value) => {
233
+ this.currentDirection = value;
234
+ })
235
+
236
+ if(this.superDataElements?.length>0){
237
+ this.dataElements=this.superDataElements;
238
+ this.buildForm();
239
+ this.isLoaded = true;
240
+ }else {
241
+ this.loadData();
242
+ }
243
+ }
244
+
245
+ private loadData() {
246
+ if (this.isPending) {
247
+ this.fields.forEach(field => {
248
+ field.readonly = true;
249
+ });
250
+ } else {
251
+ this.fields.forEach(field => {
252
+ field.readonly = false;
253
+ });
254
+ }
255
+
256
+ this.filterRequest.pendingPage = this.isPending
257
+ this.backendService.getItemsByFilter(this.filterRequest, this.pageInfo.apiUri).subscribe(resp => {
258
+ if (resp?.valid) {
259
+ this.dataElements = resp.body;
260
+ this.totalElements = resp.totalSize || 0;
261
+ this.noDataFound = resp.body.length < 1;
262
+ this.pagesCount = resp.pagesCount || 1;
263
+ this.pageIndex = this.filterRequest.pageIndex + 1;
264
+ this.buildForm();
265
+ this.isLoaded = true;
266
+ }
267
+ });
268
+ }
269
+
270
+ private buildForm() {
271
+ this.formParam = this.fb.group({
272
+ dataFormArray: this.fb.array(this.dataElements.map(item => this.fb.group(buildFormFields(this.fields, item)))),
273
+ });
274
+ }
275
+
276
+ onPageChange(event: number) {
277
+ this.getNext(event - 1);
278
+ this.config.currentPage = event;
279
+ }
280
+ getNext($event: number) {
281
+ this.filterRequest.pageIndex = $event;
282
+ this.loadData()
283
+ }
284
+
285
+ extractFieldName(element: any, property: string) {
286
+ if (property.includes('.')) {
287
+ return property.split('.').reduce((acc, part) => acc && acc[part], element);
288
+ } else {
289
+ return element[property];
290
+ }
291
+ }
292
+
293
+ get visibleColumns() {
294
+ return this.fields.filter(column => column.visible).map(column => column.property);
295
+ }
296
+
297
+
298
+ ngOnChanges(changes: SimpleChanges): void {
299
+ if (changes["enforceRefresh"] && !changes["enforceRefresh"].isFirstChange() && changes["enforceRefresh"].currentValue === true) {
300
+ // this.loadData();
301
+ }
302
+ }
303
+
304
+ onSelectItem(row: any) {
305
+ if (this.pageInfo.selfRouting) {
306
+ const mode = this.isPending ? 'pending' : 'view';
307
+ const url = `${this.pageInfo.listRoutePath || this.router.url}/${mode}`;
308
+ this.router.navigate([`${url}`, row?.id]);
309
+ }
310
+ const action = SELECT_RECORD_ACTION;
311
+ action.id = row?.id;
312
+ // this.userAction.emit(action)
313
+ this.selectedItem = row;
314
+ }
315
+
316
+ openNewTab(row) {
317
+ if (!this.pageInfo.embededTableOnly) {
318
+ const mode = this.isPending ? 'pending' : 'view';
319
+ window.open(`${this.pageInfo.listRoutePath}/${mode}` + '/' + row?.id);
320
+ }
321
+ }
322
+
323
+
324
+ getField(element, column: FieldInfo) {
325
+ return element.controls[column.property];
326
+ }
327
+
328
+ fieldButtonEvent(column, element, actionId: number) {
329
+ this.doSaveApproveAction(element, actionId);
330
+ }
331
+
332
+ patchLookupValue($event: LookupItem, property: string) {
333
+ this.formUpdated.emit(this.selectedItem)
334
+ }
335
+
336
+ addNewItem() {
337
+ const currentValues = this.formParam?.get('dataFormArray')?.value;
338
+ if (currentValues) {
339
+ this.dataElements = [...currentValues];
340
+ }
341
+ this.dataElements.push({});
342
+ this.buildForm();
343
+ }
344
+
345
+
346
+ doSaveApproveAction(element, userActionId) {
347
+ let actionId = getWfActionId(element.value.stateType);
348
+ if (userActionId === REJECT && this.isPending) {
349
+ actionId =3
350
+ }
351
+ let request = new DoActionRequest();
352
+ request.actionId = actionId;
353
+ request.subject = element.value;
354
+
355
+ if (this.actionRequestCallback) {
356
+ request = this.actionRequestCallback(request);
357
+ if (request.subject.id === "") {
358
+ request.subject.id = null;
359
+ request.subject.stateType = "NEW";
360
+ }
361
+ }
362
+
363
+ if (request.subject.id === "") {
364
+ request.subject.id = null;
365
+ request.subject.stateType = "NEW";
366
+ }
367
+
368
+
369
+ const dialogRef = this.dialog.open(ActionCommentComponent, {
370
+ data: {label: userActionId === 2 ? 'save' : 'reject', isTermination: false},
371
+ width: '600px',
372
+ height: 'auto',
373
+ direction: this.currentDirection
374
+ });
375
+ console.log(actionId)
376
+ dialogRef.afterClosed().subscribe(result => {
377
+ if (result) {
378
+ request.comment = result.comment;
379
+ this.backendService.doActionWithAttachments(request, [], this.pageInfo!).subscribe(resp => {
380
+ if (resp.valid) {
381
+ this.loadData();
382
+ console.log("actionId", actionId);
383
+ let message = '';
384
+ if (actionId === 1 ) {
385
+ message = 'saved_successfully' ;
386
+ } else if (actionId ===2 ) {
387
+ message = 'updated_successfully';
388
+ } else if (actionId ===3 ) {
389
+ message = 'successful_reject_message';
390
+ } else if (actionId ===4 ) {
391
+ message = 'approve_successfully';
392
+ }
393
+ this.backendService.topPanelMessage$.next(new SnackMessage(message, true, 'success'));
394
+ }else {
395
+ const x = resp.message?.length >0 ? resp.message[0].errorMessage : 'FAILED_CONTACT_ADMIN';
396
+ this.backendService.topPanelMessage$.next(new SnackMessage(x, true, 'error'));
397
+ }
398
+ this.saveActionEmitter.emit({item:request.subject, resp});
399
+ });
400
+ }
401
+ });
402
+ }
403
+ protected readonly getPositiveWfActionKey = getPositiveWfActionKey;
404
+ protected readonly getNegativeWfActionKey = getNegativeWfActionKey;
405
+ protected readonly SAVE = SAVE;
406
+ protected readonly REJECT = REJECT;
407
+
408
+
409
+ setMonthAndYear(normalizedMonthAndYear: Moment, picker: MatDatepicker<Moment>, element, column) {
410
+ const date = new FormControl(moment());
411
+ const ctrlValue = date.value;
412
+ ctrlValue.year(normalizedMonthAndYear.year());
413
+ ctrlValue.month(1);
414
+ ctrlValue.dayOfYear(1);
415
+ element.controls[column.property].setValue(ctrlValue);
416
+ picker.close();
417
+ }
418
+
419
+ switchViewMode(b: boolean) {
420
+ this.isPending = b;
421
+ this.loadData();
422
+ }
423
+
424
+ addBulkItems() {
425
+ const merged: any[] = [];
426
+
427
+ this.dataFormArray.controls.forEach((group: AbstractControl) => {
428
+ merged.push(group.value);
429
+ });
430
+
431
+ let request = new DoActionRequest();
432
+ request.actionId = 1;
433
+
434
+ request.subject = { invoices: merged };
435
+
436
+ if (this.actionRequestCallback) {
437
+ request = this.actionRequestCallback(request);
438
+
439
+ request.subject.invoices = request.subject.invoices.map((item: any) => {
440
+ if (item.id === "") {
441
+ item.id = null;
442
+ item.stateType = "NEW";
443
+ }
444
+ return item;
445
+ });
446
+ }
447
+
448
+ request.subject.invoices = request.subject.invoices.map((item: any) => {
449
+ if (item.id === "") {
450
+ item.id = null;
451
+ item.stateType = "NEW";
452
+ }
453
+ return item;
454
+ });
455
+
456
+
457
+
458
+ const dialogRef = this.dialog.open(ActionCommentComponent, {
459
+ data: {label: 'save' , isTermination: false},
460
+ width: '600px',
461
+ height: 'auto',
462
+ direction: this.currentDirection
463
+ });
464
+ dialogRef.afterClosed().subscribe(result => {
465
+ if (result) {
466
+ request.comment = result.comment;
467
+ this.backendService.doActionWithAttachment(request, this.selectedFileFromUploader, this.pageInfo!).subscribe(resp => {
468
+ if (resp.valid) {
469
+ this.clearBulkItems();
470
+ this.backendService.topPanelMessage$.next(new SnackMessage('saved_successfully', true, 'success'));
471
+ this.loadData();
472
+ }else {
473
+ this.backendService.topPanelMessage$.next(new SnackMessage(this.pageInfo.labelsSection + '.' + resp.message?.[0]?.errorCode, true, 'error'));
474
+ }
475
+ this.saveAttachmentEmitter.emit({item:request.subject, resp});
476
+ });
477
+ }
478
+ }); }
479
+
480
+ @ViewChild('fileUpload') fileUpload: ElementRef<HTMLInputElement>;
481
+
482
+ handleFileUpload($event: File) {
483
+ let actionId = getWfActionId('NEW');
484
+ let request = new DoActionRequest();
485
+ request.actionId = actionId;
486
+
487
+ this.selectedFileFromUploader = $event;
488
+
489
+ }
490
+
491
+ shouldDisableBulkAdd() {
492
+ const hasFile = !!this.selectedFileFromUploader;
493
+ return (!this.formParam?.valid || this.dataFormArray.controls.length === 0) && !hasFile;
494
+ }
495
+ handleEquationChange(event: { value: any[], valid: boolean }, element: FormGroup, column: any): void {
496
+ element.value[column.property] = event.value;
497
+ const { value, valid } = event;
498
+ element.get(column.property)?.setValue(value);
499
+ if (!valid) {
500
+ element.get(column.property)?.setErrors({ invalidEquation: true });
501
+ } else {
502
+ element.get(column.property)?.setErrors(null);
503
+ }
504
+ }
505
+
506
+ clearBulkItems() {
507
+ this.dataElements = [];
508
+ this.selectedFileFromUploader = null;
509
+ this.uploaderComponent.clearFile();
510
+ this.buildForm();
511
+ this.formUpdated.emit(this.formParam);
512
+ }
513
+
514
+ hasDataToClear(): boolean {
515
+ return (this.dataElements && this.dataElements.length > 0) || !!this.selectedFileFromUploader;
516
+ }
517
+ getOptionValue(item: any) {
518
+ const value = typeof item === 'object' ?
519
+ item.englishName : item;
520
+ return value;
521
+ }
522
+
523
+ disabledSaveButton(element) {
524
+ return !element.valid || (!this.isPending && element.value.stateType == 'PENDING');
525
+ }
526
+
527
+ doSearch() {
528
+ if (this.searchForm.valid) {
529
+ const rawValues = this.searchForm.getRawValue();
530
+ this.filterRequest.pageIndex=0;
531
+ this.filterRequest.filters = [];
532
+ this.searchFormFields.forEach(x => {
533
+ const value = rawValues[x.property];
534
+ if (value !== null && value !== undefined && value !== '') {
535
+ const filter = new Filter({
536
+ key: 0,
537
+ label: x.property,
538
+ fieldName: x.searchAttribute,
539
+ valueObject : x.searchAttribute.includes('.') ? value[x.searchAttribute.split('.').pop()] : value,
540
+ operator: x.searchOperator,
541
+ filterType: 'FILED_FILTER'
542
+ });
543
+ this.filterRequest.filters.push(filter);
544
+ }
545
+ });
546
+ this.loadData();
547
+ } else {
548
+ this.backendService.topPanelMessage$.next(new SnackMessage('INVALID_SEARCH_FORM', true, 'error'));
549
+ }
550
+ }
551
+
552
+ showSearch() {
553
+ return this.searchFormFields?.length > 0;
554
+ }
555
+
556
+ clearSearch() {
557
+ this.searchForm.get('sectorType').setValue({id:-100, englishName:'aaa', code:'aaa', arabicName:'aaa'});
558
+ this.searchForm.reset();
559
+ this.doSearch();
560
+ }
561
+
562
+ updateSearchForm($event: FormGroup) {
563
+ this.searchForm = $event
564
+ }
565
+
566
+ validSearchData() {
567
+ return !this.searchForm.valid || true;
568
+ }
569
+
570
+ }
@@ -0,0 +1,31 @@
1
+ <div fxLayout="row" fxLayoutGap="10px" fxFlexFill fxLayoutAlign="start center">
2
+ <ng-container *ngFor="let item of items; let i = index">
3
+ <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="5px">
4
+ <ng-container [ngSwitch]="item.type">
5
+ <ng-container *ngSwitchCase="'lookup'">
6
+ <app-auto-complete
7
+ fxFlex
8
+ [field]="field"
9
+ [form]="form"
10
+ [defaultValue]="item.value"
11
+ (selectedValue)="onLookupChange(i, $event)">
12
+ </app-auto-complete>
13
+ </ng-container>
14
+
15
+ <ng-container *ngSwitchCase="'dropdown'">
16
+ <mat-form-field appearance="outline" fxFlex="none" style="width: 100px">
17
+ <mat-select [disabled]="readOnly" [value]="item.value" (selectionChange)="onDropdownChange(i, $event.value)">
18
+ <mat-option *ngFor="let opt of operators" [value]="opt.value">
19
+ {{ opt.label }}
20
+ </mat-option>
21
+ </mat-select>
22
+ </mat-form-field>
23
+ </ng-container>
24
+ </ng-container>
25
+ </div>
26
+ </ng-container>
27
+
28
+ <button [disabled]="isPending" mat-icon-button color="warn" (click)="onClearAll()" *ngIf="items.length > 0">
29
+ <mat-icon>delete</mat-icon>
30
+ </button>
31
+ </div>
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { EquationBuilderComponent } from './equation-builder.component';
4
+
5
+ describe('EquationBuilderComponent', () => {
6
+ let component: EquationBuilderComponent;
7
+ let fixture: ComponentFixture<EquationBuilderComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [EquationBuilderComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(EquationBuilderComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });