@unifylib/ui-lib 1.0.3 → 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 (155) hide show
  1. package/ng-package.json +7 -7
  2. package/package.json +14 -12
  3. package/src/lib/base-model/SearchStrConfig.ts +12 -12
  4. package/src/lib/base-model/api-response.ts +23 -23
  5. package/src/lib/base-model/audit-log-entry.ts +7 -7
  6. package/src/lib/base-model/button-action-settings.ts +29 -25
  7. package/src/lib/base-model/column-def.model.ts +34 -34
  8. package/src/lib/base-model/do-action-request.ts +11 -11
  9. package/src/lib/base-model/feature-item.ts +9 -0
  10. package/src/lib/base-model/field-action.ts +7 -7
  11. package/src/lib/base-model/field-filter.model.ts +7 -14
  12. package/src/lib/base-model/field-info.ts +102 -98
  13. package/src/lib/base-model/field-predicate.model.ts +7 -7
  14. package/src/lib/base-model/filter-request.ts +27 -27
  15. package/src/lib/base-model/filter.model.ts +49 -49
  16. package/src/lib/base-model/get-items-list.ts +24 -24
  17. package/src/lib/base-model/index.ts +11 -11
  18. package/src/lib/base-model/items-total.model.ts +12 -0
  19. package/src/lib/base-model/line-item.model.ts +18 -0
  20. package/src/lib/base-model/lookupItem.ts +21 -21
  21. package/src/lib/base-model/null-snackmessage.ts +9 -9
  22. package/src/lib/base-model/page-info.ts +54 -51
  23. package/src/lib/base-model/report-request.model.ts +33 -33
  24. package/src/lib/base-model/response-envelop.model.ts +15 -15
  25. package/src/lib/base-model/snack-message.model.ts +14 -14
  26. package/src/lib/base-model/snackmessage-interface.ts +7 -7
  27. package/src/lib/base-model/table-column.interface.ts +29 -29
  28. package/src/lib/base-model/table-page-user-action.interface.ts +33 -33
  29. package/src/lib/base-model/workflow/workflow-steps.model.ts +9 -9
  30. package/src/lib/base-model/workflow/workflow.model.ts +52 -52
  31. package/src/lib/components/action-comment/action-comment.component.css +52 -0
  32. package/src/lib/components/action-comment/action-comment.component.html +47 -0
  33. package/src/lib/components/{rejection-comment → action-comment}/action-comment.component.spec.ts +23 -23
  34. package/src/lib/components/{rejection-comment → action-comment}/action-comment.component.ts +102 -86
  35. package/src/lib/components/action-confirmation/action-confirmation.component.css +46 -34
  36. package/src/lib/components/action-confirmation/action-confirmation.component.html +32 -18
  37. package/src/lib/components/action-confirmation/action-confirmation.component.spec.ts +23 -23
  38. package/src/lib/components/action-confirmation/action-confirmation.component.ts +58 -58
  39. package/src/lib/components/activity-report-form/activity-report-form.component.html +110 -109
  40. package/src/lib/components/activity-report-form/activity-report-form.component.scss +69 -0
  41. package/src/lib/components/activity-report-form/activity-report-form.component.spec.ts +25 -25
  42. package/src/lib/components/activity-report-form/activity-report-form.component.ts +616 -605
  43. package/src/lib/components/advanced-filter/field-filter/field-filter.component.html +8 -0
  44. package/src/lib/components/advanced-filter/field-filter/field-filter.component.scss +0 -0
  45. package/src/lib/components/advanced-filter/field-filter/field-filter.component.spec.ts +25 -0
  46. package/src/lib/components/advanced-filter/field-filter/field-filter.component.ts +55 -0
  47. package/src/lib/components/advanced-filter/filter-builder/filter-builder.component.html +36 -0
  48. package/src/lib/components/advanced-filter/filter-builder/filter-builder.component.scss +130 -0
  49. package/src/lib/components/advanced-filter/filter-builder/filter-builder.component.spec.ts +25 -0
  50. package/src/lib/components/advanced-filter/filter-builder/filter-builder.component.ts +186 -0
  51. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.css +51 -51
  52. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.html +23 -23
  53. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.spec.ts +23 -23
  54. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.ts +69 -69
  55. package/src/lib/components/audit-log-list/audit-log.component.html +26 -23
  56. package/src/lib/components/audit-log-list/audit-log.component.scss +50 -0
  57. package/src/lib/components/audit-log-list/audit-log.component.spec.ts +25 -25
  58. package/src/lib/components/audit-log-list/audit-log.component.ts +114 -116
  59. package/src/lib/components/auto-complete/auto-complete.component.css +55 -14
  60. package/src/lib/components/auto-complete/auto-complete.component.html +45 -29
  61. package/src/lib/components/auto-complete/auto-complete.component.spec.ts +23 -23
  62. package/src/lib/components/auto-complete/auto-complete.component.ts +331 -330
  63. package/src/lib/components/base-form/base-form.component.html +59 -58
  64. package/src/lib/components/base-form/base-form.component.scss +68 -0
  65. package/src/lib/components/base-form/base-form.component.spec.ts +25 -25
  66. package/src/lib/components/base-form/base-form.component.ts +323 -305
  67. package/src/lib/components/base-form-canvas/base-form-canvas.component.css +196 -22
  68. package/src/lib/components/base-form-canvas/base-form-canvas.component.html +1095 -1006
  69. package/src/lib/components/base-form-canvas/base-form-canvas.component.spec.ts +23 -23
  70. package/src/lib/components/base-form-canvas/base-form-canvas.component.ts +680 -573
  71. package/src/lib/components/base-input-dialog/base-input-dialog.component.css +67 -0
  72. package/src/lib/components/base-input-dialog/base-input-dialog.component.html +47 -42
  73. package/src/lib/components/base-input-dialog/base-input-dialog.component.spec.ts +23 -23
  74. package/src/lib/components/base-input-dialog/base-input-dialog.component.ts +77 -78
  75. package/src/lib/components/base-table/base-table.component.html +268 -242
  76. package/src/lib/components/base-table/base-table.component.scss +140 -31
  77. package/src/lib/components/base-table/base-table.component.spec.ts +25 -25
  78. package/src/lib/components/base-table/base-table.component.ts +621 -568
  79. package/src/lib/components/button-actions/button-actions.component.html +27 -28
  80. package/src/lib/components/button-actions/button-actions.component.scss +101 -6
  81. package/src/lib/components/button-actions/button-actions.component.spec.ts +23 -23
  82. package/src/lib/components/button-actions/button-actions.component.ts +70 -72
  83. package/src/lib/components/editable-base-table/editable-base-table.component.html +337 -372
  84. package/src/lib/components/editable-base-table/editable-base-table.component.scss +126 -44
  85. package/src/lib/components/editable-base-table/editable-base-table.component.spec.ts +25 -25
  86. package/src/lib/components/editable-base-table/editable-base-table.component.ts +579 -570
  87. package/src/lib/components/equation-builder/equation-builder.component.css +39 -0
  88. package/src/lib/components/equation-builder/equation-builder.component.html +31 -31
  89. package/src/lib/components/equation-builder/equation-builder.component.spec.ts +23 -23
  90. package/src/lib/components/equation-builder/equation-builder.component.ts +119 -121
  91. package/src/lib/components/item-line-editor/item-line-editor.component.html +102 -0
  92. package/src/lib/components/item-line-editor/item-line-editor.component.scss +152 -0
  93. package/src/lib/components/item-line-editor/item-line-editor.component.spec.ts +23 -0
  94. package/src/lib/components/item-line-editor/item-line-editor.component.ts +306 -0
  95. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.css +19 -11
  96. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.html +38 -38
  97. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.spec.ts +23 -23
  98. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.ts +315 -317
  99. package/src/lib/components/paginator/paginator.component.css +65 -25
  100. package/src/lib/components/paginator/paginator.component.html +30 -34
  101. package/src/lib/components/paginator/paginator.component.ts +87 -94
  102. package/src/lib/components/report-details-dialog/report-details-dialog.component.css +17 -17
  103. package/src/lib/components/report-details-dialog/report-details-dialog.component.html +16 -16
  104. package/src/lib/components/report-details-dialog/report-details-dialog.component.spec.ts +23 -23
  105. package/src/lib/components/report-details-dialog/report-details-dialog.component.ts +111 -113
  106. package/src/lib/components/report-form/report-form.component.html +92 -94
  107. package/src/lib/components/report-form/report-form.component.scss +51 -0
  108. package/src/lib/components/report-form/report-form.component.spec.ts +25 -25
  109. package/src/lib/components/report-form/report-form.component.ts +599 -588
  110. package/src/lib/components/search-bar/search-bar.component.html +51 -62
  111. package/src/lib/components/search-bar/search-bar.component.scss +63 -8
  112. package/src/lib/components/search-bar/search-bar.component.spec.ts +25 -25
  113. package/src/lib/components/search-bar/search-bar.component.ts +68 -70
  114. package/src/lib/components/section-form-canvas/section-form-canvas.component.html +43 -0
  115. package/src/lib/components/section-form-canvas/section-form-canvas.component.scss +81 -0
  116. package/src/lib/components/section-form-canvas/section-form-canvas.component.spec.ts +23 -0
  117. package/src/lib/components/section-form-canvas/section-form-canvas.component.ts +67 -0
  118. package/src/lib/components/shared/action-button/action-button.component.html +12 -0
  119. package/src/lib/components/shared/action-button/action-button.component.scss +45 -0
  120. package/src/lib/components/shared/action-button/action-button.component.ts +51 -0
  121. package/src/lib/components/shared/action-card/action-card.component.html +78 -0
  122. package/src/lib/components/shared/action-card/action-card.component.scss +238 -0
  123. package/src/lib/components/shared/action-card/action-card.component.ts +56 -0
  124. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.css +135 -54
  125. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.html +36 -22
  126. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.spec.ts +23 -23
  127. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.ts +71 -45
  128. package/src/lib/components/shared-list/shared-list.component.html +17 -17
  129. package/src/lib/components/shared-list/shared-list.component.spec.ts +23 -23
  130. package/src/lib/components/shared-list/shared-list.component.ts +53 -53
  131. package/src/lib/components/snackbar-static/snackbar-static.component.html +20 -0
  132. package/src/lib/components/snackbar-static/snackbar-static.component.scss +135 -0
  133. package/src/lib/components/snackbar-static/snackbar-static.component.ts +26 -0
  134. package/src/lib/components/title-bar/title-bar.component.html +35 -31
  135. package/src/lib/components/title-bar/title-bar.component.scss +126 -23
  136. package/src/lib/components/title-bar/title-bar.component.spec.ts +23 -23
  137. package/src/lib/components/title-bar/title-bar.component.ts +126 -119
  138. package/src/lib/services/backend-service.ts +287 -286
  139. package/src/lib/services/index.ts +3 -3
  140. package/src/lib/services/top-panel.ts +17 -17
  141. package/src/lib/services/trigger-form.service.ts +11 -11
  142. package/src/lib/share-module/shared-module.ts +10 -10
  143. package/src/lib/utils/base-utils.ts +102 -102
  144. package/src/lib/validators/date-range-validator.ts +31 -31
  145. package/src/lib/validators/index.ts +3 -3
  146. package/src/lib/validators/match-list.validator.ts +10 -10
  147. package/src/lib/validators/multi-email-validator.ts +15 -15
  148. package/src/public-api.ts +29 -21
  149. package/tsconfig.lib.json +15 -15
  150. package/tsconfig.lib.prod.json +11 -11
  151. package/tsconfig.spec.json +15 -15
  152. package/src/lib/components/rejection-comment/action-comment.component.css +0 -33
  153. package/src/lib/components/rejection-comment/action-comment.component.html +0 -46
  154. package/src/lib/styles/invoiceq-theme.scss +0 -252
  155. package/src/lib/styles/styles.scss +0 -1723
@@ -1,286 +1,287 @@
1
- import {Inject, Injectable} from "@angular/core";
2
- import {HttpClient, HttpErrorResponse, HttpHeaders, HttpParams} from "@angular/common/http";
3
- import {Observable, of, Subject} from "rxjs";
4
- import {catchError, distinctUntilChanged} from "rxjs/operators";
5
- import {SnackMessage} from "../base-model/snack-message.model";
6
- import {PageInfo} from "../base-model/page-info";
7
- import {TranslateService} from "@ngx-translate/core";
8
- import {ColumnDef} from "../base-model/column-def.model";
9
- import {TableColumn} from "../base-model/table-column.interface";
10
- import {GetItemsList} from "../base-model/get-items-list";
11
- import {FieldAction} from "../base-model/field-action";
12
- import {Workflow} from "../base-model/workflow/workflow.model";
13
- import {ReportRequest} from "../base-model/report-request.model";
14
- import {FilterRequest} from "../base-model/filter-request";
15
- import {ResponseEnvelop} from "../base-model/response-envelop.model";
16
- import {FormGroup} from "@angular/forms";
17
- import { ActivatedRoute } from "@angular/router";
18
- import {TopPanel} from "./top-panel";
19
- import {DoActionRequest} from "../base-model/do-action-request";
20
- import {MatDialog} from "@angular/material/dialog";
21
- import {ActionConfirmationComponent} from "../components/action-confirmation/action-confirmation.component";
22
-
23
- const WORKFLOW_STATES_MAP: Record<number, string> = {
24
- 1: 'New',
25
- 2: 'Pending',
26
- 3: 'Terminated',
27
- 4: 'Completed',
28
- 5: 'Updated',
29
- 6: 'Default'
30
- };
31
-
32
- const EXCLUDED_REPORT_COLUMNS = ['listAction','button', 'checkbox'];
33
- @Injectable({
34
- providedIn: 'root'
35
- })
36
- export class BackendService {
37
- public topPanelMessage$ = new Subject<SnackMessage>();
38
- // @ts-ignore
39
- public parentForm: FormGroup;
40
- public fieldAction$ = new Subject<FieldAction>();
41
- public isEmptyItems: boolean = true;
42
-
43
- constructor(private http: HttpClient,
44
- private topPanel: TopPanel,
45
- private translateService: TranslateService,
46
- private route: ActivatedRoute,
47
- private dialog: MatDialog,
48
- @Inject('config') private config: any,
49
- @Inject('secretsManager') private secretsManager: any) {
50
-
51
- this.topPanelMessage$.subscribe(msg => {
52
- this.topPanel.topPanelMessage$.next(msg);
53
- })
54
- }
55
-
56
- set defaults(value: any | undefined) {
57
- }
58
-
59
- get defaults(): any | undefined {
60
- return {};
61
- }
62
-
63
- getStatusDescription(element: any, workflow: Workflow) {
64
- if (element?.stepId) {
65
-
66
- let index = workflow?.workflowSteps?.findIndex(s => s.stepId === element.stepId);
67
- if (index > -1) {
68
- return this.translateService.getDefaultLang() === 'ar' ?
69
- workflow?.workflowSteps[index].stepNameAr || workflow?.workflowSteps[index].stepName:
70
- workflow?.workflowSteps[index].stepName;
71
- // return this.translateService.instant(workflow?.workflowSteps[index].stepName);
72
- } else {
73
- return this.translateService.instant('INVENTORY.inprocessStatus');
74
- }
75
- } else {
76
- if (element.statusId === 4 && element.statusDescription) {
77
- return element.statusDescription;
78
- } else if (element.statusId) {
79
- return this.translateService.instant(WORKFLOW_STATES_MAP[element.statusId]);
80
- } else {
81
- return "unknown";
82
- }
83
- }
84
- }
85
- //sss
86
- getItemsByFilter(reportRequest: any, apiUrl: string): Observable<any> {
87
- const url = `${this.getApiBasePath()}/api/v1${apiUrl}/list`;
88
- return this.http.post(url, reportRequest, { headers: this.buildSecuredHeader()}).pipe(
89
- distinctUntilChanged(),
90
- catchError(err => of(err.message || err)));
91
- }
92
-
93
- getItemAuditLog(reportRequest: any, apiUrl: string): Observable<any> {
94
- const url = `${this.getApiBasePath()}/api/v1${apiUrl}/audit-log`;
95
- return this.http.post(url, reportRequest, { headers: this.buildSecuredHeader()}).pipe(
96
- distinctUntilChanged(),
97
- catchError(err => of(err.message || err)));
98
- }
99
-
100
-
101
- private buildSecuredHeader() {
102
- const headers = new HttpHeaders({
103
- 'Content-Type': 'application/json',
104
- Authorization: this.config.getAuthToken()
105
- });
106
- return headers;
107
- }
108
-
109
- public buildFormSecuredHeader() {
110
- const headers = new HttpHeaders({
111
- Authorization: this.config.getAuthToken()
112
- });
113
- return headers;
114
- }
115
-
116
- labelKey(column: any, pageInfo: PageInfo) {
117
- const configuredKey = column.label ? column.label : column.property;
118
-
119
- if (configuredKey && configuredKey.trim() !== '' && configuredKey.startsWith(pageInfo.labelsSection)) {
120
- return configuredKey;
121
- }
122
-
123
- return `${pageInfo.labelsSection}.${configuredKey}`;
124
- }
125
-
126
-
127
- private buildReportColumn(columns: TableColumn<any>[], pageInfo: PageInfo): ColumnDef[] {
128
- let columnDef: ColumnDef[] = [];
129
-
130
- columns.filter(x => !EXCLUDED_REPORT_COLUMNS.includes(x.type)).forEach((c, index) => {
131
- let transLabel = this.translateService.instant(this.labelKey(c,pageInfo));
132
- let transGroup = pageInfo.supportGroupingInExport ?
133
- c.group.trim() ? this.translateService.instant(c.group) : ' ' : null;
134
- if (c.type === 'workflowStatus') {
135
- transLabel = this.translateService.instant('workflowStatus');
136
- }
137
- if ((c.reportVisible === true) || (c.visible === true && c.reportVisible !== false)) {
138
- columnDef.push(new ColumnDef(c, index, transLabel, this.translateService.getDefaultLang(),transGroup));
139
- }
140
- });
141
- return columnDef;
142
- }
143
-
144
- private base64ToArrayBuffer(base64: string) {
145
- const binaryString = window.atob(base64); // Comment this if not using base64
146
- const bytes = new Uint8Array(binaryString.length);
147
- return bytes.map((byte, i) => binaryString.charCodeAt(i));
148
- }
149
-
150
- buildReportRequest(columns: TableColumn<any>[], title: string | string[], filterRequest: FilterRequest, reportType: any, pageInfo: PageInfo, searchStr: string ,orientation='PORTRAIT'): ReportRequest {
151
- const columnDef = this.buildReportColumn(columns, pageInfo);
152
- const reportRequest = new ReportRequest({
153
- dataset: [], filter: "",
154
- columns: columnDef,
155
- // sessionId: this.topPanel.userSession().sessionId,
156
- sessionId: this.config.getAuthToken(),
157
- title: this.translateService.instant(title),
158
- prefLang: this.translateService.getDefaultLang(),
159
- reportType: reportType,
160
- searchStr: searchStr,
161
- filterRequest: filterRequest,
162
- orientation: orientation});
163
- return reportRequest;
164
- }
165
-
166
- getLookupItemsByMultiFilter(listItems: GetItemsList, filterRequest?: FilterRequest): Observable<any> {
167
- listItems.pageSize = 100;
168
- filterRequest.pageSize = 100;
169
- const params = new HttpParams().set('searchStr', listItems.searchStr);
170
- let url = `${this.getApiBasePath()}/api/v1/${listItems.apiUri}`;
171
- return this.http.post(url, filterRequest, { headers: this.buildSecuredHeader(), params: params}).pipe(
172
- distinctUntilChanged(),
173
- catchError(err => of(err.message || err)));
174
- }
175
- getLookupItemsByFilter(listItems: GetItemsList, cascadedId?: any): Observable<any> {
176
- listItems.pageSize = 500;
177
- const params = new HttpParams().set('searchStr', listItems.searchStr);
178
- let url = `${this.getApiBasePath()}/api/v1/${listItems.apiUri}`;
179
- if (cascadedId) {
180
- url = url + `/${cascadedId}`
181
- }
182
-
183
- return this.http.post(url, listItems,{ headers: this.buildSecuredHeader()}).pipe(
184
- distinctUntilChanged(),
185
- catchError(err => of(err.message || err)));
186
- }
187
-
188
-
189
-
190
- downloadReport(reportRequest: ReportRequest, pageApiPath : string, readyPath? : boolean ) {
191
- const s = readyPath === true ? `/api/v1${pageApiPath}` : `/api/v1${pageApiPath}/extractAndDownloadListReport`;
192
- return this.http.post<ResponseEnvelop>(this.getApiBasePath() + s, reportRequest, {headers: this.buildSecuredHeader()}).subscribe(
193
- (resp:ResponseEnvelop) => {
194
- if (resp.valid) {
195
- if (resp.body) {
196
- const filename = reportRequest.title + "." + reportRequest.reportType;
197
- const blob = new Blob([this.base64ToArrayBuffer(resp.body)]);
198
- if (navigator.msSaveBlob) {
199
- navigator.msSaveBlob(blob, filename);
200
- } else {
201
- const link = document.createElement('a');
202
- // Browsers that support HTML5 download attribute
203
- if (link.download !== undefined) {
204
- const url = URL.createObjectURL(blob);
205
- link.setAttribute('href', url);
206
- link.setAttribute('download', filename);
207
- link.style.visibility = 'hidden';
208
- document.body.appendChild(link);
209
- link.click();
210
- document.body.removeChild(link);
211
- }
212
- }
213
- } else {
214
- this.topPanel.topPanelMessage$.next(new SnackMessage(resp.message.toString(), true, 'info'));
215
- }
216
- } else {
217
- this.topPanel.topPanelMessage$.next(new SnackMessage(resp.message.toString(), false, 'error'));
218
- }
219
- }
220
- );
221
-
222
- }
223
-
224
- private getApiBasePath(){
225
- return this.config.getBaseApi();
226
- }
227
-
228
- doActionWithAttachments(request: DoActionRequest, param2: any[], pageInfo: PageInfo) {
229
- const url = `${this.getApiBasePath()}/api/v1${pageInfo.apiUri}/doActionWithAttachments`;
230
- const formData: FormData = new FormData();
231
- formData.set('doActionRequest', new Blob([JSON.stringify(request)], {
232
- type: "application/json"
233
- }));
234
-
235
- return this.http.post(url, formData, { headers: this.buildFormSecuredHeader() }).pipe(
236
- distinctUntilChanged(),
237
- catchError((error: HttpErrorResponse) => {
238
- return of(error.error);
239
- })
240
- );
241
-
242
- }
243
- doActionWithAttachment(request: DoActionRequest, file: File, pageInfo: PageInfo) {
244
- const url = `${this.getApiBasePath()}/api/v1${pageInfo.apiUri}/doActionWithAttachments`;
245
- const formData: FormData = new FormData();
246
-
247
- formData.append('files', file);
248
- formData.set('doActionRequest', new Blob([JSON.stringify(request)], {
249
- type: "application/json"
250
- }));
251
-
252
- return this.http.post<any>(url, formData, {
253
- headers: this.buildFormSecuredHeader()
254
- }).pipe(
255
- distinctUntilChanged(),
256
- catchError((error: HttpErrorResponse) => {
257
- // Transform the error into a fake success-like response
258
- return of(error.error); // This will now be passed to `next` in subscribe()
259
- })
260
- );
261
- }
262
-
263
- encrypt(message: any) {
264
- return this.secretsManager.encryptSecret(message);
265
- }
266
-
267
- decrypt(secret: any) {
268
- return this.secretsManager.decryptSecret(secret);
269
- }
270
-
271
- public getConfirmation(): Observable<any> {
272
- const dialogRef = this.dialog.open(ActionConfirmationComponent, {
273
- data: {acceptActionLabel: 'accept',rejectActionLabel:'return', warningMsg: 'confirmation_message'},
274
- width: '600px',
275
- height: 'auto'
276
- });
277
- return dialogRef.afterClosed();
278
- }
279
-
280
- }
281
-
282
- declare global {
283
- interface Navigator {
284
- msSaveBlob: (blobOrBase64: Blob | string, filename: string) => void
285
- }
286
- }
1
+ import {Inject, Injectable} from "@angular/core";
2
+ import {HttpClient, HttpErrorResponse, HttpHeaders, HttpParams} from "@angular/common/http";
3
+ import {Observable, of, Subject} from "rxjs";
4
+ import {catchError, distinctUntilChanged} from "rxjs/operators";
5
+ import {SnackMessage} from "../base-model/snack-message.model";
6
+ import {PageInfo} from "../base-model/page-info";
7
+ import {TranslateService} from "@ngx-translate/core";
8
+ import {ColumnDef} from "../base-model/column-def.model";
9
+ import {TableColumn} from "../base-model/table-column.interface";
10
+ import {GetItemsList} from "../base-model/get-items-list";
11
+ import {FieldAction} from "../base-model/field-action";
12
+ import {Workflow} from "../base-model/workflow/workflow.model";
13
+ import {ReportRequest} from "../base-model/report-request.model";
14
+ import {FilterRequest} from "../base-model/filter-request";
15
+ import {ResponseEnvelop} from "../base-model/response-envelop.model";
16
+ import {FormGroup} from "@angular/forms";
17
+ import { ActivatedRoute } from "@angular/router";
18
+ import {TopPanel} from "./top-panel";
19
+ import {DoActionRequest} from "../base-model/do-action-request";
20
+ import {MatDialog} from "@angular/material/dialog";
21
+ import {ActionConfirmationComponent} from "../components/action-confirmation/action-confirmation.component";
22
+
23
+ const WORKFLOW_STATES_MAP: Record<number, string> = {
24
+ 1: 'New',
25
+ 2: 'Pending',
26
+ 3: 'Terminated',
27
+ 4: 'Completed',
28
+ 5: 'Updated',
29
+ 6: 'Default'
30
+ };
31
+
32
+ const EXCLUDED_REPORT_COLUMNS = ['listAction','button', 'checkbox'];
33
+ @Injectable({
34
+ providedIn: 'root'
35
+ })
36
+ export class BackendService {
37
+ public topPanelMessage$ = new Subject<SnackMessage>();
38
+ // @ts-ignore
39
+ public parentForm: FormGroup;
40
+ public childForm: FormGroup;
41
+ public fieldAction$ = new Subject<FieldAction>();
42
+ public isEmptyItems: boolean = true;
43
+
44
+ constructor(private http: HttpClient,
45
+ private topPanel: TopPanel,
46
+ private translateService: TranslateService,
47
+ private route: ActivatedRoute,
48
+ private dialog: MatDialog,
49
+ @Inject('config') private config: any,
50
+ @Inject('secretsManager') private secretsManager: any) {
51
+
52
+ this.topPanelMessage$.subscribe(msg => {
53
+ this.topPanel.topPanelMessage$.next(msg);
54
+ })
55
+ }
56
+
57
+ set defaults(value: any | undefined) {
58
+ }
59
+
60
+ get defaults(): any | undefined {
61
+ return {};
62
+ }
63
+
64
+ getStatusDescription(element: any, workflow: Workflow) {
65
+ if (element?.stepId) {
66
+
67
+ let index = workflow?.workflowSteps?.findIndex(s => s.stepId === element.stepId);
68
+ if (index > -1) {
69
+ return this.translateService.getDefaultLang() === 'ar' ?
70
+ workflow?.workflowSteps[index].stepNameAr || workflow?.workflowSteps[index].stepName:
71
+ workflow?.workflowSteps[index].stepName;
72
+ // return this.translateService.instant(workflow?.workflowSteps[index].stepName);
73
+ } else {
74
+ return this.translateService.instant('INVENTORY.inprocessStatus');
75
+ }
76
+ } else {
77
+ if (element.statusId === 4 && element.statusDescription) {
78
+ return element.statusDescription;
79
+ } else if (element.statusId) {
80
+ return this.translateService.instant(WORKFLOW_STATES_MAP[element.statusId]);
81
+ } else {
82
+ return "unknown";
83
+ }
84
+ }
85
+ }
86
+ //sss
87
+ getItemsByFilter(reportRequest: any, apiUrl: string): Observable<any> {
88
+ const url = `${this.getApiBasePath()}/api/v1${apiUrl}/list`;
89
+ return this.http.post(url, reportRequest, { headers: this.buildSecuredHeader()}).pipe(
90
+ distinctUntilChanged(),
91
+ catchError(err => of(err.message || err)));
92
+ }
93
+
94
+ getItemAuditLog(reportRequest: any, apiUrl: string): Observable<any> {
95
+ const url = `${this.getApiBasePath()}/api/v1${apiUrl}/audit-log`;
96
+ return this.http.post(url, reportRequest, { headers: this.buildSecuredHeader()}).pipe(
97
+ distinctUntilChanged(),
98
+ catchError(err => of(err.message || err)));
99
+ }
100
+
101
+
102
+ private buildSecuredHeader() {
103
+ const headers = new HttpHeaders({
104
+ 'Content-Type': 'application/json',
105
+ Authorization: this.config.getAuthToken()
106
+ });
107
+ return headers;
108
+ }
109
+
110
+ public buildFormSecuredHeader() {
111
+ const headers = new HttpHeaders({
112
+ Authorization: this.config.getAuthToken()
113
+ });
114
+ return headers;
115
+ }
116
+
117
+ labelKey(column: any, pageInfo: PageInfo) {
118
+ const configuredKey = column.label ? column.label : column.property;
119
+
120
+ if (configuredKey && configuredKey.trim() !== '' && configuredKey.startsWith(pageInfo.labelsSection)) {
121
+ return configuredKey;
122
+ }
123
+
124
+ return `${pageInfo.labelsSection}.${configuredKey}`;
125
+ }
126
+
127
+
128
+ private buildReportColumn(columns: TableColumn<any>[], pageInfo: PageInfo): ColumnDef[] {
129
+ let columnDef: ColumnDef[] = [];
130
+
131
+ columns.filter(x => !EXCLUDED_REPORT_COLUMNS.includes(x.type)).forEach((c, index) => {
132
+ let transLabel = this.translateService.instant(this.labelKey(c,pageInfo));
133
+ let transGroup = pageInfo.supportGroupingInExport ?
134
+ c.group.trim() ? this.translateService.instant(c.group) : ' ' : null;
135
+ if (c.type === 'workflowStatus') {
136
+ transLabel = this.translateService.instant('workflowStatus');
137
+ }
138
+ if ((c.reportVisible === true) || (c.visible === true && c.reportVisible !== false)) {
139
+ columnDef.push(new ColumnDef(c, index, transLabel, this.translateService.getDefaultLang(),transGroup));
140
+ }
141
+ });
142
+ return columnDef;
143
+ }
144
+
145
+ private base64ToArrayBuffer(base64: string) {
146
+ const binaryString = window.atob(base64); // Comment this if not using base64
147
+ const bytes = new Uint8Array(binaryString.length);
148
+ return bytes.map((byte, i) => binaryString.charCodeAt(i));
149
+ }
150
+
151
+ buildReportRequest(columns: TableColumn<any>[], title: string | string[], filterRequest: FilterRequest, reportType: any, pageInfo: PageInfo, searchStr: string ,orientation='PORTRAIT'): ReportRequest {
152
+ const columnDef = this.buildReportColumn(columns, pageInfo);
153
+ const reportRequest = new ReportRequest({
154
+ dataset: [], filter: "",
155
+ columns: columnDef,
156
+ // sessionId: this.topPanel.userSession().sessionId,
157
+ sessionId: this.config.getAuthToken(),
158
+ title: this.translateService.instant(title),
159
+ prefLang: this.translateService.getDefaultLang(),
160
+ reportType: reportType,
161
+ searchStr: searchStr,
162
+ filterRequest: filterRequest,
163
+ orientation: orientation});
164
+ return reportRequest;
165
+ }
166
+
167
+ getLookupItemsByMultiFilter(listItems: GetItemsList, filterRequest?: FilterRequest): Observable<any> {
168
+ listItems.pageSize = 100;
169
+ filterRequest.pageSize = 100;
170
+ const params = new HttpParams().set('searchStr', listItems.searchStr);
171
+ let url = `${this.getApiBasePath()}/api/v1/${listItems.apiUri}`;
172
+ return this.http.post(url, filterRequest, { headers: this.buildSecuredHeader(), params: params}).pipe(
173
+ distinctUntilChanged(),
174
+ catchError(err => of(err.message || err)));
175
+ }
176
+ getLookupItemsByFilter(listItems: GetItemsList, cascadedId?: any): Observable<any> {
177
+ listItems.pageSize = 500;
178
+ const params = new HttpParams().set('searchStr', listItems.searchStr);
179
+ let url = `${this.getApiBasePath()}/api/v1/${listItems.apiUri}`;
180
+ if (cascadedId) {
181
+ url = url + `/${cascadedId}`
182
+ }
183
+
184
+ return this.http.post(url, listItems,{ headers: this.buildSecuredHeader()}).pipe(
185
+ distinctUntilChanged(),
186
+ catchError(err => of(err.message || err)));
187
+ }
188
+
189
+
190
+
191
+ downloadReport(reportRequest: ReportRequest, pageApiPath : string, readyPath? : boolean ) {
192
+ const s = readyPath === true ? `/api/v1${pageApiPath}` : `/api/v1${pageApiPath}/extractAndDownloadListReport`;
193
+ return this.http.post<ResponseEnvelop>(this.getApiBasePath() + s, reportRequest, {headers: this.buildSecuredHeader()}).subscribe(
194
+ (resp:ResponseEnvelop) => {
195
+ if (resp.valid) {
196
+ if (resp.body) {
197
+ const filename = reportRequest.title + "." + reportRequest.reportType;
198
+ const blob = new Blob([this.base64ToArrayBuffer(resp.body)]);
199
+ if (navigator.msSaveBlob) {
200
+ navigator.msSaveBlob(blob, filename);
201
+ } else {
202
+ const link = document.createElement('a');
203
+ // Browsers that support HTML5 download attribute
204
+ if (link.download !== undefined) {
205
+ const url = URL.createObjectURL(blob);
206
+ link.setAttribute('href', url);
207
+ link.setAttribute('download', filename);
208
+ link.style.visibility = 'hidden';
209
+ document.body.appendChild(link);
210
+ link.click();
211
+ document.body.removeChild(link);
212
+ }
213
+ }
214
+ } else {
215
+ this.topPanel.topPanelMessage$.next(new SnackMessage(resp.message.toString(), true, 'info'));
216
+ }
217
+ } else {
218
+ this.topPanel.topPanelMessage$.next(new SnackMessage(resp.message.toString(), false, 'error'));
219
+ }
220
+ }
221
+ );
222
+
223
+ }
224
+
225
+ private getApiBasePath(){
226
+ return this.config.getBaseApi();
227
+ }
228
+
229
+ doActionWithAttachments(request: DoActionRequest, param2: any[], pageInfo: PageInfo) {
230
+ const url = `${this.getApiBasePath()}/api/v1${pageInfo.apiUri}/doActionWithAttachments`;
231
+ const formData: FormData = new FormData();
232
+ formData.set('doActionRequest', new Blob([JSON.stringify(request)], {
233
+ type: "application/json"
234
+ }));
235
+
236
+ return this.http.post(url, formData, { headers: this.buildFormSecuredHeader() }).pipe(
237
+ distinctUntilChanged(),
238
+ catchError((error: HttpErrorResponse) => {
239
+ return of(error.error);
240
+ })
241
+ );
242
+
243
+ }
244
+ doActionWithAttachment(request: DoActionRequest, file: File, pageInfo: PageInfo) {
245
+ const url = `${this.getApiBasePath()}/api/v1${pageInfo.apiUri}/doActionWithAttachments`;
246
+ const formData: FormData = new FormData();
247
+
248
+ formData.append('files', file);
249
+ formData.set('doActionRequest', new Blob([JSON.stringify(request)], {
250
+ type: "application/json"
251
+ }));
252
+
253
+ return this.http.post<any>(url, formData, {
254
+ headers: this.buildFormSecuredHeader()
255
+ }).pipe(
256
+ distinctUntilChanged(),
257
+ catchError((error: HttpErrorResponse) => {
258
+ // Transform the error into a fake success-like response
259
+ return of(error.error); // This will now be passed to `next` in subscribe()
260
+ })
261
+ );
262
+ }
263
+
264
+ encrypt(message: any) {
265
+ return this.secretsManager.encryptSecret(message);
266
+ }
267
+
268
+ decrypt(secret: any) {
269
+ return this.secretsManager.decryptSecret(secret);
270
+ }
271
+
272
+ public getConfirmation(): Observable<any> {
273
+ const dialogRef = this.dialog.open(ActionConfirmationComponent, {
274
+ data: {acceptActionLabel: 'accept',rejectActionLabel:'return', warningMsg: 'confirmation_message'},
275
+ width: '600px',
276
+ height: 'auto'
277
+ });
278
+ return dialogRef.afterClosed();
279
+ }
280
+
281
+ }
282
+
283
+ declare global {
284
+ interface Navigator {
285
+ msSaveBlob: (blobOrBase64: Blob | string, filename: string) => void
286
+ }
287
+ }
@@ -1,3 +1,3 @@
1
- export * from './backend-service';
2
- export * from './top-panel';
3
- export * from './trigger-form.service'
1
+ export * from './backend-service';
2
+ export * from './top-panel';
3
+ export * from './trigger-form.service'
@@ -1,17 +1,17 @@
1
- import {Injectable} from "@angular/core";
2
- import {BehaviorSubject} from "rxjs";
3
- import {SnackMessage} from "../base-model/snack-message.model";
4
-
5
- @Injectable({
6
- providedIn: 'root'
7
- })
8
- export class TopPanel {
9
-
10
- public topPanelMessage$ = new BehaviorSubject<SnackMessage>({
11
- message: '',
12
- translate: false,
13
- type: 'info',
14
- translateParams: {}
15
- });
16
-
17
- }
1
+ import {Injectable} from "@angular/core";
2
+ import {BehaviorSubject} from "rxjs";
3
+ import {SnackMessage} from "../base-model/snack-message.model";
4
+
5
+ @Injectable({
6
+ providedIn: 'root'
7
+ })
8
+ export class TopPanel {
9
+
10
+ public topPanelMessage$ = new BehaviorSubject<SnackMessage>({
11
+ message: '',
12
+ translate: false,
13
+ type: 'info',
14
+ translateParams: {}
15
+ });
16
+
17
+ }