@pega/angular-sdk-overrides 23.1.10 → 24.2.10

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 (137) hide show
  1. package/lib/designSystemExtension/alert-banner/alert-banner.component.ts +1 -1
  2. package/lib/designSystemExtension/case-create-stage/case-create-stage.component.ts +1 -1
  3. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +7 -4
  4. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss +2 -1
  5. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +3 -1
  6. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +1 -1
  7. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +4 -1
  8. package/lib/designSystemExtension/material-vertical-tabs/material-vertical-tabs.component.html +1 -1
  9. package/lib/designSystemExtension/operator/operator.component.ts +11 -6
  10. package/lib/designSystemExtension/pulse/pulse.component.ts +7 -7
  11. package/lib/field/auto-complete/auto-complete.component.ts +17 -14
  12. package/lib/field/cancel-alert/cancel-alert.component.ts +0 -2
  13. package/lib/field/check-box/check-box.component.html +16 -15
  14. package/lib/field/check-box/check-box.component.scss +14 -1
  15. package/lib/field/check-box/check-box.component.ts +128 -45
  16. package/lib/field/currency/currency.component.html +16 -7
  17. package/lib/field/currency/currency.component.ts +55 -20
  18. package/lib/field/date/date.component.html +1 -6
  19. package/lib/field/date/date.component.ts +22 -39
  20. package/lib/field/date-time/date-time.component.html +6 -7
  21. package/lib/field/date-time/date-time.component.ts +28 -45
  22. package/lib/field/decimal/decimal.component.html +14 -4
  23. package/lib/field/decimal/decimal.component.ts +47 -7
  24. package/lib/field/dropdown/dropdown.component.ts +132 -21
  25. package/lib/field/email/email.component.ts +14 -4
  26. package/lib/field/group/group.component.html +1 -1
  27. package/lib/field/group/group.component.ts +6 -2
  28. package/lib/field/integer/integer.component.html +1 -1
  29. package/lib/field/integer/integer.component.ts +13 -5
  30. package/lib/field/multiselect/multiselect.component.html +33 -0
  31. package/lib/field/multiselect/multiselect.component.scss +7 -0
  32. package/lib/field/multiselect/multiselect.component.spec.ts +21 -0
  33. package/lib/field/multiselect/multiselect.component.ts +369 -0
  34. package/lib/field/multiselect/utils.ts +209 -0
  35. package/lib/field/percentage/percentage.component.html +17 -6
  36. package/lib/field/percentage/percentage.component.ts +51 -12
  37. package/lib/field/phone/phone.component.html +1 -1
  38. package/lib/field/phone/phone.component.ts +11 -14
  39. package/lib/field/radio-buttons/radio-buttons.component.ts +9 -12
  40. package/lib/field/rich-text/config-ext.json +10 -0
  41. package/lib/field/rich-text/rich-text.component.html +1 -1
  42. package/lib/field/rich-text/rich-text.component.ts +8 -6
  43. package/lib/field/scalar-list/scalar-list.component.ts +4 -4
  44. package/lib/field/text/text.component.ts +2 -0
  45. package/lib/field/text-area/text-area.component.html +2 -1
  46. package/lib/field/text-area/text-area.component.ts +13 -8
  47. package/lib/field/text-input/text-input.component.html +1 -1
  48. package/lib/field/text-input/text-input.component.ts +13 -5
  49. package/lib/field/time/time.component.html +3 -2
  50. package/lib/field/time/time.component.ts +23 -7
  51. package/lib/field/url/url.component.html +2 -1
  52. package/lib/field/url/url.component.ts +15 -5
  53. package/lib/field/user-reference/user-reference.component.html +42 -45
  54. package/lib/field/user-reference/user-reference.component.ts +73 -27
  55. package/lib/infra/Containers/base-components/flow-container-base.component.ts +22 -0
  56. package/lib/infra/Containers/base-components/helper.ts +89 -0
  57. package/lib/infra/Containers/flow-container/flow-container.component.html +9 -4
  58. package/lib/infra/Containers/flow-container/flow-container.component.ts +38 -33
  59. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +41 -9
  60. package/lib/infra/Containers/preview-view-container/preview-view-container.component.ts +1 -1
  61. package/lib/infra/Containers/view-container/helper.ts +22 -0
  62. package/lib/infra/Containers/view-container/view-container.component.ts +5 -18
  63. package/lib/infra/assignment/assignment.component.ts +37 -39
  64. package/lib/infra/dashboard-filter/dashboard-filter.component.ts +0 -1
  65. package/lib/infra/defer-load/defer-load.component.ts +9 -12
  66. package/lib/infra/multi-step/multi-step.component.html +1 -1
  67. package/lib/infra/multi-step/multi-step.component.scss +1 -0
  68. package/lib/infra/navbar/navbar.component.html +4 -4
  69. package/lib/infra/navbar/navbar.component.ts +9 -6
  70. package/lib/infra/root-container/root-container.component.ts +3 -3
  71. package/lib/infra/stages/stages.component.scss +2 -2
  72. package/lib/infra/view/view.component.html +7 -20
  73. package/lib/infra/view/view.component.ts +21 -3
  74. package/lib/template/app-shell/app-shell.component.ts +20 -2
  75. package/lib/template/banner-page/config-ext.json +9 -0
  76. package/lib/template/base/details-template-base.ts +67 -0
  77. package/lib/template/base/form-template-base.ts +10 -0
  78. package/lib/template/case-summary/case-summary.component.ts +38 -4
  79. package/lib/template/case-view/case-view.component.html +7 -7
  80. package/lib/template/case-view/case-view.component.scss +2 -0
  81. package/lib/template/case-view/case-view.component.ts +8 -19
  82. package/lib/template/confirmation/confirmation.component.ts +1 -1
  83. package/lib/template/data-reference/data-reference.component.ts +37 -43
  84. package/lib/template/default-form/default-form.component.html +0 -4
  85. package/lib/template/default-form/default-form.component.ts +7 -23
  86. package/lib/template/details/details.component.ts +7 -41
  87. package/lib/template/details-narrow-wide/details-narrow-wide.component.ts +6 -39
  88. package/lib/template/details-one-column/details-one-column.component.ts +7 -42
  89. package/lib/template/details-sub-tabs/details-sub-tabs.component.html +1 -2
  90. package/lib/template/details-sub-tabs/details-sub-tabs.component.ts +5 -37
  91. package/lib/template/details-three-column/details-three-column.component.ts +7 -43
  92. package/lib/template/details-two-column/details-two-column.component.ts +8 -44
  93. package/lib/template/details-wide-narrow/details-wide-narrow.component.ts +7 -42
  94. package/lib/template/dynamic-tabs/dynamic-tabs.component.html +3 -0
  95. package/lib/template/dynamic-tabs/dynamic-tabs.component.ts +8 -4
  96. package/lib/template/field-group-template/field-group-template.component.ts +4 -14
  97. package/lib/template/field-value-list/field-value-list.component.html +8 -3
  98. package/lib/template/field-value-list/field-value-list.component.scss +2 -1
  99. package/lib/template/field-value-list/field-value-list.component.ts +1 -0
  100. package/lib/template/inline-dashboard-page/config-ext.json +9 -0
  101. package/lib/template/inline-dashboard-page/inline-dashboard-page.component.ts +2 -2
  102. package/lib/template/list-view/list-view.component.html +9 -6
  103. package/lib/template/list-view/list-view.component.scss +11 -0
  104. package/lib/template/list-view/list-view.component.ts +60 -32
  105. package/lib/template/list-view/listViewHelpers.ts +1 -2
  106. package/lib/template/narrow-wide-form/narrow-wide-form.component.ts +1 -1
  107. package/lib/template/one-column/one-column.component.ts +4 -3
  108. package/lib/template/one-column-tab/one-column-tab.component.ts +1 -1
  109. package/lib/template/page/page.component.ts +1 -1
  110. package/lib/template/promoted-filters/promoted-filters.component.ts +1 -1
  111. package/lib/template/repeating-structures/repeating-structures.component.ts +2 -3
  112. package/lib/template/simple-table/simple-table.component.ts +0 -2
  113. package/lib/template/simple-table-manual/helpers.ts +2 -2
  114. package/lib/template/simple-table-manual/simple-table-manual.component.html +1 -1
  115. package/lib/template/simple-table-manual/simple-table-manual.component.scss +1 -0
  116. package/lib/template/simple-table-manual/simple-table-manual.component.ts +60 -28
  117. package/lib/template/simple-table-select/simple-table-select.component.ts +5 -7
  118. package/lib/template/three-column/three-column.component.ts +4 -3
  119. package/lib/template/two-column/two-column.component.ts +4 -3
  120. package/lib/template/two-column-tab/two-column-tab.component.ts +1 -1
  121. package/lib/template/wide-narrow-form/wide-narrow-form.component.ts +4 -3
  122. package/lib/template/wide-narrow-page/wide-narrow-page.component.ts +1 -1
  123. package/lib/template/wss-nav-bar/wss-nav-bar.component.html +1 -1
  124. package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +5 -4
  125. package/lib/widget/attachment/attachment.component.html +50 -26
  126. package/lib/widget/attachment/attachment.component.scss +118 -0
  127. package/lib/widget/attachment/attachment.component.ts +256 -503
  128. package/lib/widget/case-history/case-history.component.ts +1 -2
  129. package/lib/widget/feed-container/feed-container.component.ts +7 -11
  130. package/lib/widget/file-utility/file-utility.component.html +2 -2
  131. package/lib/widget/file-utility/file-utility.component.ts +15 -22
  132. package/lib/widget/list-utility/list-utility.component.html +1 -1
  133. package/lib/widget/quick-create/config-ext.json +9 -0
  134. package/lib/widget/quick-create/quick-create.component.ts +1 -1
  135. package/lib/widget/todo/todo.component.html +8 -7
  136. package/lib/widget/todo/todo.component.ts +97 -86
  137. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
- import { Component, OnInit, Input, NgZone, forwardRef, OnDestroy } from '@angular/core';
1
+ import { Component, OnInit, Input, NgZone, forwardRef, OnDestroy, ViewChild, ElementRef } from '@angular/core';
2
2
  import { FormGroup } from '@angular/forms';
3
3
  import { CommonModule } from '@angular/common';
4
4
  import { MatButtonModule } from '@angular/material/button';
5
+ import { MatMenuModule } from '@angular/material/menu';
6
+ import { MatIconModule } from '@angular/material/icon';
5
7
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
6
8
  import download from 'downloadjs';
7
9
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
@@ -21,7 +23,7 @@ interface AttachmentProps extends Omit<PConnFieldProps, 'value'> {
21
23
  templateUrl: './attachment.component.html',
22
24
  styleUrls: ['./attachment.component.scss'],
23
25
  standalone: true,
24
- imports: [CommonModule, MatProgressSpinnerModule, MatButtonModule, forwardRef(() => ComponentMapperComponent)]
26
+ imports: [CommonModule, MatProgressSpinnerModule, MatMenuModule, MatIconModule, MatButtonModule, forwardRef(() => ComponentMapperComponent)]
25
27
  })
26
28
  export class AttachmentComponent implements OnInit, OnDestroy {
27
29
  @Input() pConn$: typeof PConnect;
@@ -29,6 +31,7 @@ export class AttachmentComponent implements OnInit, OnDestroy {
29
31
 
30
32
  // For interaction with AngularPConnect
31
33
  angularPConnectData: AngularPConnectData = {};
34
+ @ViewChild('uploader', { static: false }) fileInput: ElementRef;
32
35
 
33
36
  label$ = '';
34
37
  value$: any;
@@ -37,16 +40,8 @@ export class AttachmentComponent implements OnInit, OnDestroy {
37
40
  bDisabled$ = false;
38
41
  bVisible$ = true;
39
42
  bLoading$ = false;
40
- arFiles$: any[] = [];
41
- arFileList$: any[] = [];
42
- removeFileFromList$: any;
43
- arMenuList$: any[] = [];
44
43
  bShowSelector$ = true;
45
- bShowJustDelete$ = false;
46
- att_valueRef: any;
47
44
  att_categoryName: string;
48
- att_id: string;
49
- myFiles: any;
50
45
  fileTemp: any = {};
51
46
  caseID: any;
52
47
  allowMultiple$ = false;
@@ -55,7 +50,17 @@ export class AttachmentComponent implements OnInit, OnDestroy {
55
50
  validateMessage: string | undefined = '';
56
51
  valueRef: string;
57
52
  imagePath$: string;
58
-
53
+ localizedVal = PCore.getLocaleUtils().getLocaleValue;
54
+ localeCategory = 'CosmosFields';
55
+ uploadMultipleFilesLabel = this.localizedVal('file_upload_text_multiple', this.localeCategory);
56
+ uploadSingleFileLabel = this.localizedVal('file_upload_text_one', this.localeCategory);
57
+ filesWithError: any = [];
58
+ files: any = [];
59
+ categoryName: string;
60
+ displayMode: string | undefined;
61
+ srcImg: any;
62
+ deleteIcon: string;
63
+ tempFilesToBeUploaded: any[];
59
64
  constructor(
60
65
  private angularPConnect: AngularPConnectService,
61
66
  private utils: Utils,
@@ -65,13 +70,36 @@ export class AttachmentComponent implements OnInit, OnDestroy {
65
70
  ngOnInit(): void {
66
71
  // // First thing in initialization is registering and subscribing to the AngularPConnect service
67
72
  this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
68
-
69
- this.removeFileFromList$ = { onClick: this._removeFileFromList.bind(this) };
70
-
71
73
  this.caseID = PCore.getStoreValue('.pyID', 'caseInfo.content', this.pConn$.getContextName());
72
-
73
- // let configProps: any = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps());
74
+ this.srcImg = this.utils.getImageSrc('document-doc', this.utils.getSDKStaticContentUrl());
75
+ this.deleteIcon = this.utils.getImageSrc('trash', this.utils.getSDKStaticContentUrl());
74
76
  this.checkAndUpdate();
77
+ this.getAttachments();
78
+ }
79
+
80
+ getAttachments() {
81
+ let tempUploadedFiles = this.getCurrentAttachmentsList(this.getAttachmentKey(this.valueRef), this.pConn$.getContextName());
82
+ tempUploadedFiles = tempUploadedFiles.filter(f => f.label === this.valueRef && f.delete !== true);
83
+ this.files?.map(f => {
84
+ return f.responseProps?.pzInsKey && !f.responseProps.pzInsKey.includes('temp')
85
+ ? {
86
+ ...f,
87
+ props: {
88
+ ...f.props,
89
+ onDelete: () => this.deleteFile(f)
90
+ }
91
+ }
92
+ : { ...f };
93
+ });
94
+ this.files = [...this.files, ...tempUploadedFiles];
95
+ PCore.getPubSubUtils().subscribe(
96
+ PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
97
+ this.resetAttachmentStoredState.bind(this),
98
+ this.caseID
99
+ );
100
+ return () => {
101
+ PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, this.caseID);
102
+ };
75
103
  }
76
104
 
77
105
  checkAndUpdate() {
@@ -85,77 +113,15 @@ export class AttachmentComponent implements OnInit, OnDestroy {
85
113
  }
86
114
  }
87
115
 
88
- ngOnDestroy(): void {
89
- if (this.angularPConnectData.unsubscribeFn) {
90
- this.angularPConnectData.unsubscribeFn();
91
- }
92
-
93
- PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, this.caseID);
94
- }
95
-
96
116
  // Callback passed when subscribing to store change
97
117
  onStateChange() {
98
118
  this.checkAndUpdate();
99
119
  }
100
120
 
101
- updateAttachmentsInfo() {
102
- // @ts-ignore - Property 'attachmentsInfo' does not exist on type 'C11nEnv'
103
- if (!this.pConn$.attachmentsInfo) {
104
- // @ts-ignore - Property 'attachmentsInfo' does not exist on type 'C11nEnv'
105
- this.pConn$.attachmentsInfo = {
106
- type: 'File',
107
- attachmentFieldName: this.att_valueRef,
108
- category: this.att_categoryName
109
- };
110
- }
111
- }
112
-
113
- processFile(file, i) {
114
- file.props.type = file.responseProps.pyMimeFileExtension;
115
- file.props.mimeType = file.responseProps.pyMimeFileExtension;
116
- file.props.ID = file.responseProps.pzInsKey;
117
-
118
- const arMenuList = [
119
- {
120
- icon: 'download',
121
- text: this.pConn$.getLocalizedValue('Download', '', ''),
122
- onClick: () => this._downloadFileFromList(this.value$.pxResults[i])
123
- },
124
- {
125
- icon: 'trash',
126
- text: this.pConn$.getLocalizedValue('Delete', '', ''),
127
- onClick: () => this._removeFileFromList(this.arFileList$[i])
128
- }
129
- ];
130
-
131
- const arFilesAttachmentIDs: any = [];
132
- this.arFileList$.forEach(arFile => {
133
- arFilesAttachmentIDs.push(arFile.id);
134
- });
135
-
136
- if (!arFilesAttachmentIDs.includes(file.props.ID)) {
137
- this.arFileList$.push(
138
- this.getNewListUtilityItemProps({
139
- att: file.props,
140
- downloadFile: null,
141
- cancelFile: null,
142
- deleteFile: null,
143
- removeFile: null
144
- })
145
- );
146
- }
147
-
148
- this.arFileList$[i].actions = arMenuList;
149
- this.arFileList$[i].noDeleteIcon = true;
150
-
151
- this.bShowSelector$ = false;
152
- }
153
-
154
121
  updateSelf() {
155
122
  const configProps: AttachmentProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as AttachmentProps;
156
- const stateProps: any = this.pConn$.getStateProps();
157
-
158
- const { value, label, extensions } = configProps;
123
+ const stateProps = this.pConn$.getStateProps();
124
+ const { value, label, extensions, displayMode } = configProps;
159
125
 
160
126
  if (configProps.required != null) {
161
127
  this.bRequired$ = this.utils.getBooleanValue(configProps.required);
@@ -177,114 +143,62 @@ export class AttachmentComponent implements OnInit, OnDestroy {
177
143
  this.allowMultiple$ = this.utils.getBooleanValue(configProps.allowMultiple);
178
144
  }
179
145
 
180
- this.bShowJustDelete$ = true;
181
146
  this.label$ = label;
182
147
  this.value$ = value;
183
148
  this.status = stateProps.status;
149
+
184
150
  this.validateMessage = this.angularPConnectData.validateMessage;
185
151
  this.extensions$ = extensions;
186
- this.valueRef = (this.pConn$.getStateProps() as any).value;
152
+ this.valueRef = this.pConn$.getStateProps().value;
187
153
  this.valueRef = this.valueRef.startsWith('.') ? this.valueRef.substring(1) : this.valueRef;
188
-
154
+ this.displayMode = displayMode;
189
155
  /* this is a temporary fix because required is supposed to be passed as a boolean and NOT as a string */
190
156
  let { required, disabled } = configProps;
191
157
  [required, disabled] = [required, disabled].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
192
158
 
193
- this.att_categoryName = '';
159
+ this.categoryName = '';
194
160
  if (value && value.pyCategoryName) {
195
- this.att_categoryName = value.pyCategoryName;
161
+ this.categoryName = value.pyCategoryName;
196
162
  }
197
163
 
198
- this.att_valueRef = (this.pConn$.getStateProps() as any).value;
199
- this.att_valueRef = this.att_valueRef.indexOf('.') === 0 ? this.att_valueRef.substring(1) : this.att_valueRef;
164
+ if (value?.pxResults && +value.pyCount > 0) {
165
+ this.files = value.pxResults.map(f => this.buildFilePropsFromResponse(f));
166
+ }
200
167
 
201
168
  this.updateAttachments();
202
169
  }
203
170
 
204
- updateAttachments() {
205
- const attachmentsFromServer = this.value$ && this.value$.pxResults && +this.value$.pyCount > 0;
206
-
207
- if (attachmentsFromServer) {
208
- this.updateAttachmentsFromServer();
209
- } else {
210
- // Get the attachments from the Redux
211
- this.myFiles = this.getCurrentAttachmentsList(this.getAttachmentKey(this.att_valueRef), this.pConn$.getContextName());
212
-
213
- if (this.myFiles?.length && this.arFiles$.length === 0) {
214
- this.arFileList$ = this.myFiles.map(att => {
215
- return this.getNewListUtilityItemProps({
216
- att,
217
- downloadFile: null,
218
- cancelFile: null,
219
- deleteFile: null,
220
- removeFile: null
221
- });
222
- });
171
+ buildFilePropsFromResponse(respObj) {
172
+ return {
173
+ props: {
174
+ meta: `${respObj.pyCategoryName}, ${respObj.pxCreateOperator}`,
175
+ name: respObj.pyAttachName,
176
+ icon: this.utils.getIconFromFileType(respObj.pyMimeFileExtension)
177
+ },
178
+ responseProps: {
179
+ ...respObj
223
180
  }
224
-
225
- const myFilesAttachmentIDs: any = [];
226
- this.myFiles.forEach(myFile => {
227
- myFilesAttachmentIDs.push(myFile.ID);
228
- });
229
-
230
- this.arFiles$.forEach(arFile => {
231
- if (!myFilesAttachmentIDs.includes(arFile.ID)) {
232
- this.myFiles = [...this.myFiles, arFile];
233
- }
234
- });
235
- }
236
-
237
- this.bShowJustDelete$ = true;
238
- this.bShowSelector$ = !(this.arFileList$?.length > 0) || this.allowMultiple$;
239
-
240
- if (this.arFileList$.length > 0) {
241
- this.CheckForInvalidAttachment();
242
- }
243
- PCore.getPubSubUtils().subscribe(
244
- PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
245
- this.resetAttachmentStoredState.bind(this),
246
- this.caseID
247
- );
181
+ };
248
182
  }
249
183
 
250
- updateAttachmentsFromServer() {
251
- this.value$.pxResults.forEach((attachment, i) => {
252
- const file: any = this.buildFilePropsFromResponse(attachment);
253
- if (file.responseProps) {
254
- this.updateAttachmentsInfo();
255
- if (file.responseProps.pzInsKey && !file.responseProps.pzInsKey.includes('temp')) {
256
- this.processFile(file, i);
257
- }
258
- if (file) {
259
- const currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.att_valueRef), this.pConn$.getContextName());
260
- const index = currentAttachmentList.findIndex(element => element.props.ID === file.props.ID);
261
- let tempFiles: any = [];
262
- if (index < 0) {
263
- tempFiles = [file];
264
- }
265
-
266
- PCore.getStateUtils().updateState(
267
- this.pConn$.getContextName(),
268
- this.getAttachmentKey(this.att_valueRef),
269
- [...currentAttachmentList, ...tempFiles],
270
- {
271
- pageReference: 'context_data',
272
- isArrayDeepMerge: false
273
- }
274
- );
275
- }
276
- }
277
- });
184
+ updateAttachments() {
185
+ if (this.files.length > 0 && this.displayMode !== 'DISPLAY_ONLY') {
186
+ const currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.valueRef), this.pConn$.getContextName());
187
+ // block duplicate files to redux store when added 1 after another to prevent multiple duplicates being added to the case on submit
188
+ const tempFiles = this.files.filter(f => currentAttachmentList.findIndex(fr => fr.ID === f.ID) === -1 && !f.inProgress && f.responseProps);
189
+ const updatedAttList = [...currentAttachmentList, ...tempFiles];
190
+ this.updateAttachmentState(this.pConn$, this.getAttachmentKey(this.valueRef), updatedAttList);
191
+ }
278
192
  }
279
193
 
280
194
  resetAttachmentStoredState() {
281
- PCore.getStateUtils().updateState(this.pConn$.getContextName(), this.getAttachmentKey(this.att_valueRef), undefined, {
195
+ PCore.getStateUtils().updateState(this.pConn$?.getContextName(), this.getAttachmentKey(this.valueRef), undefined, {
282
196
  pageReference: 'context_data',
283
197
  isArrayDeepMerge: false
284
198
  });
285
199
  }
286
200
 
287
- _downloadFileFromList(fileObj: any) {
201
+ downloadFile(fileObj: any) {
288
202
  PCore.getAttachmentUtils()
289
203
  // @ts-ignore - 3rd parameter "responseEncoding" should be optional
290
204
  .downloadAttachment(fileObj.pzInsKey, this.pConn$.getContextName())
@@ -304,146 +218,196 @@ export class AttachmentComponent implements OnInit, OnDestroy {
304
218
 
305
219
  getAttachmentKey = (name = '') => (name ? `attachmentsList.${name}` : 'attachmentsList');
306
220
 
307
- CheckForInvalidAttachment() {
308
- let isValid = true;
309
- this.arFileList$.forEach(file => {
310
- if (file.secondary.error) {
311
- isValid = false;
312
- }
313
- });
314
- if (isValid) {
315
- // @ts-ignore
316
- PCore.getMessageManager().clearMessages({
317
- type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
318
- property: (this.pConn$.getStateProps() as any).value,
319
- pageReference: this.pConn$.getPageReference(),
320
- context: this.pConn$.getContextName()
321
- });
322
- }
221
+ getCurrentAttachmentsList(key, context) {
222
+ return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
323
223
  }
324
224
 
325
- _removeFileFromList(item: any) {
326
- const fileListIndex = this.arFileList$.findIndex(element => element?.id === item?.id);
327
- const fileIndex = this.arFiles$.findIndex(element => element?.ID === item?.id);
225
+ validateMaxSize(fileObj, maxSizeInMB): boolean {
226
+ const fileSize = (fileObj.size / 1048576).toFixed(2);
227
+ return parseFloat(fileSize) < parseFloat(maxSizeInMB);
228
+ }
229
+
230
+ validateFileExtension = (fileObj, allowedExtensions) => {
231
+ if (!allowedExtensions) {
232
+ return true;
233
+ }
234
+ const allowedExtensionList = allowedExtensions
235
+ .toLowerCase()
236
+ .split(',')
237
+ .map(item => item.replaceAll('.', '').trim());
238
+ const extension = fileObj.name.split('.').pop().toLowerCase();
239
+ return allowedExtensionList.includes(extension);
240
+ };
241
+
242
+ updateAttachmentState(pConn, key, attachments) {
243
+ PCore.getStateUtils().updateState(this.pConn$.getContextName(), key, attachments, {
244
+ pageReference: 'context_data',
245
+ isArrayDeepMerge: false
246
+ });
247
+ }
328
248
 
329
- const attachmentsList = [];
330
- let currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.att_valueRef), this.pConn$.getContextName());
331
- if (this.value$ && this.value$.pxResults && +this.value$.pyCount > 0 && item.actions) {
332
- const updatedAttachments = currentAttachmentList.map(attachment => {
333
- if (attachment?.ID === this.arFileList$[fileListIndex].id || attachment?.props?.ID === this.arFileList$[fileListIndex].id) {
334
- return { ...attachment, delete: true, label: this.valueRef };
249
+ deleteFile(file) {
250
+ const attachmentsList: any[] = [];
251
+ let currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.valueRef), this.pConn$.getContextName());
252
+
253
+ // If file to be deleted is the one added in previous stage i.e. for which a file instance is created in server
254
+ // no need to filter currentAttachmentList as we will get another entry of file in redux with delete & label
255
+ // eslint-disable-next-line no-unsafe-optional-chaining
256
+ if (this.value$ && this.value$?.pxResults && +this.value$?.pyCount > 0 && file.responseProps && file?.responseProps?.pzInsKey !== 'temp') {
257
+ const updatedAttachments = this.files.map(f => {
258
+ if (f.responseProps && f.responseProps.pzInsKey === file.responseProps.pzInsKey) {
259
+ return { ...f, delete: true, label: this.valueRef };
335
260
  }
336
- return attachment;
261
+ return f;
337
262
  });
338
263
 
339
264
  // updating the redux store to help form-handler in passing the data to delete the file from server
340
- PCore.getStateUtils().updateState(this.pConn$.getContextName(), this.getAttachmentKey(this.att_valueRef), updatedAttachments, {
341
- pageReference: 'context_data',
342
- isArrayDeepMerge: false
343
- });
344
- } else {
345
- currentAttachmentList = currentAttachmentList.filter(f => f.ID !== item.id);
346
- PCore.getStateUtils().updateState(
347
- this.pConn$.getContextName(),
348
- this.getAttachmentKey(this.att_valueRef),
349
- [...currentAttachmentList, ...attachmentsList],
350
- {
351
- pageReference: 'context_data',
352
- isArrayDeepMerge: false
353
- }
265
+ this.updateAttachmentState(this.pConn$, this.getAttachmentKey(this.valueRef), [...updatedAttachments]);
266
+ const newlyAddedFiles = this.files.filter(f => !!f.ID);
267
+ const filesPostDelete = this.files.filter(
268
+ f => f.responseProps?.pzInsKey !== 'temp' && f.responseProps?.pzInsKey !== file.responseProps?.pzInsKey
354
269
  );
270
+ this.files = [...filesPostDelete, ...newlyAddedFiles];
271
+ } // if the file being deleted is the added in this stage i.e. whose data is not yet created in server
272
+ else {
273
+ // filter newly added files in this stage, later the updated current stage files will be added to redux once files state is updated
274
+ currentAttachmentList = currentAttachmentList.filter(f => f.ID !== file.ID);
275
+ this.files = this.files.filter(f => f.ID !== file.ID);
276
+
277
+ this.updateAttachmentState(this.pConn$, this.getAttachmentKey(this.valueRef), [...currentAttachmentList, ...attachmentsList]);
278
+ if (file.inProgress) {
279
+ // @ts-ignore - 3rd parameter "responseEncoding" should be optional
280
+ PCore.getAttachmentUtils().cancelRequest(file.ID, this.pConn$.getContextName());
281
+ }
355
282
  }
356
283
 
357
- if (fileListIndex > -1) {
358
- this.arFileList$.splice(fileListIndex, 1);
284
+ this.filesWithError = this.filesWithError?.filter(f => f.ID !== file.ID);
285
+ if (this.filesWithError.length === 0) {
286
+ this.clearFieldErrorMessages();
359
287
  }
360
- if (fileIndex > -1) {
361
- this.arFiles$.splice(fileIndex, 1);
362
- }
363
-
364
- this.CheckForInvalidAttachment();
288
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
289
+ this.fileInput && this.fileInput.nativeElement.value ? null : '';
290
+ }
365
291
 
366
- this.bShowSelector$ = !(this.arFileList$?.length > 0) || this.allowMultiple$;
292
+ onFileAdded(event) {
293
+ let addedFiles = Array.from(event.target.files);
294
+ addedFiles = this.allowMultiple$ ? addedFiles : [addedFiles[0]];
295
+ const maxAttachmentSize = PCore.getEnvironmentInfo().getMaxAttachmentSize() || '5';
296
+ this.tempFilesToBeUploaded = [
297
+ ...addedFiles.map((f: any, index) => {
298
+ f.ID = `${new Date().getTime()}I${index}`;
299
+ f.inProgress = true;
300
+ f.props = {
301
+ type: f.type,
302
+ name: f.name,
303
+ icon: this.utils.getIconFromFileType(f.type),
304
+ onDelete: () => this.deleteFile(f)
305
+ };
306
+ if (!this.validateMaxSize(f, maxAttachmentSize)) {
307
+ f.props.error = true;
308
+ f.inProgress = false;
309
+ f.props.meta = this.pConn$.getLocalizedValue(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`, '', '');
310
+ } else if (!this.validateFileExtension(f, this.extensions$)) {
311
+ f.props.error = true;
312
+ f.inProgress = false;
313
+ f.props.meta = `${this.pConn$.getLocalizedValue(
314
+ 'File has invalid extension. Allowed extensions are:',
315
+ '',
316
+ ''
317
+ )} ${this.extensions$.replaceAll('.', '')}`;
318
+ }
319
+ if (f.props.error) {
320
+ const fieldName = this.pConn$.getStateProps().value;
321
+ const context = this.pConn$.getContextName();
322
+ PCore.getMessageManager().addMessages({
323
+ messages: [
324
+ {
325
+ type: 'error',
326
+ message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
327
+ }
328
+ ],
329
+ property: fieldName,
330
+ pageReference: this.pConn$.getPageReference(),
331
+ context
332
+ });
333
+ }
334
+ return f;
335
+ })
336
+ ];
337
+ const tempFilesWithError = this.tempFilesToBeUploaded.filter(f => f.props.error);
338
+ if (tempFilesWithError.length > 0) {
339
+ this.filesWithError = tempFilesWithError;
340
+ }
341
+ if (!this.allowMultiple$) {
342
+ this.files = [...this.tempFilesToBeUploaded];
343
+ } else {
344
+ this.files = [...this.files, ...this.tempFilesToBeUploaded];
345
+ }
346
+ this.uploadFiles();
367
347
  }
368
348
 
369
- getCurrentAttachmentsList(key, context) {
370
- return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
349
+ clearFieldErrorMessages() {
350
+ const fieldName = this.pConn$.getStateProps().value;
351
+ const context = this.pConn$.getContextName();
352
+ PCore.getMessageManager().clearMessages({
353
+ type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
354
+ property: fieldName,
355
+ pageReference: this.pConn$.getPageReference(),
356
+ context
357
+ });
371
358
  }
372
359
 
373
- errorHandler(isFetchCanceled, file) {
360
+ onUploadProgress() {}
361
+
362
+ errorHandler(isFetchCanceled, attachedFile) {
374
363
  return error => {
375
364
  if (!isFetchCanceled(error)) {
376
365
  let uploadFailMsg = this.pConn$.getLocalizedValue('Something went wrong', '', '');
377
366
  if (error.response && error.response.data && error.response.data.errorDetails) {
378
367
  uploadFailMsg = this.pConn$.getLocalizedValue(error.response.data.errorDetails[0].localizedValue, '', '');
379
368
  }
380
- for (const myFile of this.myFiles) {
381
- if (myFile.ID === file.ID) {
382
- myFile.meta = uploadFailMsg;
383
- myFile.error = true;
384
- myFile.fileName = this.pConn$.getLocalizedValue('Unable to upload file', '', '');
385
- }
386
- }
387
- this.bShowSelector$ = false;
388
- this.arFileList$ = this.myFiles.map(att => {
389
- if (att.id) {
390
- return att;
391
- }
392
- return this.getNewListUtilityItemProps({
393
- att,
394
- downloadFile: null,
395
- cancelFile: null,
396
- deleteFile: null,
397
- removeFile: null
398
- });
399
- });
400
369
 
401
- PCore.getMessageManager().addMessages({
402
- // @ts-ignore
403
- messages: [
404
- {
405
- type: 'error',
406
- message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
407
- }
408
- ],
409
- property: (this.pConn$.getStateProps() as any).value,
410
- pageReference: this.pConn$.getPageReference(),
411
- context: this.pConn$.getContextName()
370
+ this.files.map(f => {
371
+ if (f.ID === attachedFile.ID) {
372
+ f.props.meta = uploadFailMsg;
373
+ f.props.error = true;
374
+ f.props.onDelete = () => this.deleteFile(f);
375
+ f.props.icon = this.utils.getIconFromFileType(f.type);
376
+ f.props.name = this.pConn$.getLocalizedValue('Unable to upload file', '', '');
377
+ f.inProgress = false;
378
+ const fieldName = this.pConn$.getStateProps().value;
379
+ const context = this.pConn$.getContextName();
380
+ // set errors to property to block submit even on errors in file upload
381
+ PCore.getMessageManager().addMessages({
382
+ messages: [
383
+ {
384
+ type: 'error',
385
+ message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
386
+ }
387
+ ],
388
+ property: fieldName,
389
+ pageReference: this.pConn$.getPageReference(),
390
+ context
391
+ });
392
+ delete f.props.progress;
393
+ }
394
+ return f;
412
395
  });
413
-
414
- this.bShowJustDelete$ = true;
415
- this.bLoading$ = false;
416
396
  }
417
397
  throw error;
418
398
  };
419
399
  }
420
400
 
421
- uploadMyFiles(event: any) {
422
- let arrAttachmentFiles: any = [];
423
- if (this.arFiles$.length) {
424
- arrAttachmentFiles = this.arFiles$;
425
- } else {
426
- arrAttachmentFiles = this.arFileList$;
427
- }
428
- this.arFiles$ = [...arrAttachmentFiles, ...this.getFiles(event.target.files)];
429
-
430
- // convert FileList to an array
431
- this.myFiles = Array.from(this.arFiles$);
432
-
433
- this.bLoading$ = true;
434
-
435
- const filesToBeUploaded = this.myFiles
401
+ uploadFiles() {
402
+ const filesToBeUploaded = this.files
436
403
  .filter(e => {
437
- if (e.id) {
438
- return false;
439
- }
440
- const isFileUploaded = e && e.progress === 100;
441
- const fileHasError = e && e.error;
404
+ const isFileUploaded = e.props && e.props.progress === 100;
405
+ const fileHasError = e.props && e.props.error;
442
406
  const isFileUploadedinLastStep = e.responseProps && e.responseProps.pzInsKey;
443
407
  return !isFileUploaded && !fileHasError && !isFileUploadedinLastStep;
444
408
  })
445
409
  .map(f =>
446
- PCore.getAttachmentUtils().uploadAttachment(
410
+ window.PCore.getAttachmentUtils().uploadAttachment(
447
411
  f,
448
412
  () => {
449
413
  this.onUploadProgress();
@@ -454,252 +418,41 @@ export class AttachmentComponent implements OnInit, OnDestroy {
454
418
  this.pConn$.getContextName()
455
419
  )
456
420
  );
457
-
458
421
  Promise.allSettled(filesToBeUploaded)
459
422
  .then((fileResponses: any) => {
460
- this.handleFileUploadSuccess(fileResponses);
461
- })
462
- .catch(error => {
463
- console.log(error);
464
- this.handleFileUploadFailure();
465
- });
466
- }
467
-
468
- handleFileUploadSuccess(fileResponses) {
469
- const successFileResponses = fileResponses.filter(fr => fr.status !== 'rejected'); // in case of deleting an in progress file, promise gets cancelled but still enters then block
470
- let reqObj;
471
- if (successFileResponses.length > 0) {
472
- const tempFilesUploaded = [...this.arFiles$.filter(file => !file.id)];
473
- let newAttachments: any = [];
474
- tempFilesUploaded.forEach(fileRes => {
475
- const index = successFileResponses.findIndex((fr: any) => fr.value.clientFileID === fileRes.ID);
476
- if (index >= 0) {
477
- reqObj = {
478
- type: 'File',
479
- label: this.att_valueRef,
480
- category: this.att_categoryName,
481
- handle: successFileResponses[index].value.ID,
482
- ID: fileRes.ID,
483
- name: fileRes.name
484
- };
485
- newAttachments = [...newAttachments, reqObj];
486
- }
487
- });
488
- const currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.att_valueRef), this.pConn$.getContextName()).filter(
489
- f => f.label !== this.att_valueRef
490
- );
491
- PCore.getStateUtils().updateState(
492
- this.pConn$.getContextName(),
493
- this.getAttachmentKey(this.att_valueRef),
494
- [...currentAttachmentList, ...newAttachments],
495
- {
496
- pageReference: 'context_data',
497
- isArrayDeepMerge: false
498
- }
499
- );
500
- this.arFiles$ = tempFilesUploaded;
501
-
502
- this.ngZone.run(() => {
503
- this.bShowSelector$ = this.allowMultiple$;
504
- this.arFiles$.forEach(file => {
505
- if (!file.error) {
506
- file.meta = this.pConn$.getLocalizedValue('File uploaded successfully', '', '');
507
- }
508
- });
509
- this.arFileList$ = this.myFiles.map(att => {
510
- if (att.id) {
511
- return att;
512
- }
513
- return this.getNewListUtilityItemProps({
514
- att,
515
- downloadFile: null,
516
- cancelFile: null,
517
- deleteFile: null,
518
- removeFile: null
423
+ fileResponses = fileResponses.filter(fr => fr.status !== 'rejected'); // in case of deleting an in progress file, promise gets cancelled but still enters then block
424
+ if (fileResponses.length > 0) {
425
+ this.files.forEach(f => {
426
+ const index = fileResponses.findIndex((fr: any) => fr.value.clientFileID === f.ID);
427
+ if (index >= 0) {
428
+ f.props.meta = this.pConn$.getLocalizedValue('Uploaded successfully', '', '');
429
+ f.props.progress = 100;
430
+ f.inProgress = false;
431
+ f.handle = fileResponses[index].value.ID;
432
+ f.label = this.valueRef;
433
+ f.category = this.categoryName;
434
+ f.responseProps = {
435
+ pzInsKey: 'temp',
436
+ pyAttachName: f.props.name
437
+ };
438
+ }
519
439
  });
520
- });
521
-
522
- this.CheckForInvalidAttachment();
523
-
524
- this.bShowJustDelete$ = true;
525
- this.bLoading$ = false;
526
- });
527
- }
528
- }
529
-
530
- handleFileUploadFailure() {
531
- this.bShowJustDelete$ = true;
532
- this.bLoading$ = false;
533
- this.bShowSelector$ = this.allowMultiple$;
534
- this.myFiles.forEach(file => {
535
- if (file?.secondary?.error) {
536
- file.meta = 'File uploaded failed';
537
- }
538
- });
539
-
540
- this.arFileList$ = this.myFiles.map(att => {
541
- return this.getNewListUtilityItemProps({
542
- att,
543
- downloadFile: null,
544
- cancelFile: null,
545
- deleteFile: null,
546
- removeFile: null
547
- });
548
- });
549
-
550
- this.bShowJustDelete$ = true;
551
- this.bLoading$ = false;
552
- }
553
-
554
- getNewListUtilityItemProps = ({ att, cancelFile, downloadFile, deleteFile, removeFile }) => {
555
- let actions;
556
- let isDownloadable = false;
557
-
558
- if (att.progress && att.progress !== 100) {
559
- actions = [
560
- {
561
- id: `Cancel-${att.ID}`,
562
- text: this.pConn$.getLocalizedValue('Cancel', '', ''),
563
- icon: 'times',
564
- onClick: cancelFile
565
- }
566
- ];
567
- } else if (att.links) {
568
- const isFile = att.type === 'FILE';
569
- const ID = att.ID.replace(/\s/gi, '');
570
- const actionsMap = new Map([
571
- [
572
- 'download',
573
- {
574
- id: `download-${ID}`,
575
- text: isFile ? this.pConn$.getLocalizedValue('Download', '', '') : this.pConn$.getLocalizedValue('Open', '', ''),
576
- icon: isFile ? 'download' : 'open',
577
- onClick: downloadFile
578
- }
579
- ],
580
- [
581
- 'delete',
582
- {
583
- id: `Delete-${ID}`,
584
- text: this.pConn$.getLocalizedValue('Delete', '', ''),
585
- icon: 'trash',
586
- onClick: deleteFile
440
+ this.updateAttachments();
441
+ if (this.filesWithError?.length === 0) {
442
+ this.clearFieldErrorMessages();
587
443
  }
588
- ]
589
- ]);
590
- actions = [];
591
- actionsMap.forEach((action, actionKey) => {
592
- if (att.links[actionKey]) {
593
- actions.push(action);
594
444
  }
445
+ })
446
+ .catch(error => {
447
+ console.log(error);
595
448
  });
596
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
597
- isDownloadable = att.links.download;
598
- } else if (att.error) {
599
- actions = [
600
- {
601
- id: `Remove-${att.ID}`,
602
- text: this.pConn$.getLocalizedValue('Remove', '', ''),
603
- icon: 'trash',
604
- onClick: removeFile
605
- }
606
- ];
607
- }
608
-
609
- return {
610
- id: att.ID,
611
- visual: {
612
- icon: this.utils.getIconForAttachment(att),
613
- progress: att.progress == 100 ? undefined : att.progress
614
- },
615
- primary: {
616
- type: att.type,
617
- name: att.error ? att.fileName : att.name,
618
- icon: 'trash',
619
- click: removeFile
620
- },
621
- secondary: {
622
- text: att.meta,
623
- error: att.error
624
- },
625
- actions
626
- };
627
- };
628
-
629
- onUploadProgress() {}
630
-
631
- getFiles(arFiles: any[]): any[] {
632
- const files = this.allowMultiple$ ? arFiles : [arFiles[0]];
633
- return this.setNewFiles(files);
634
- }
635
-
636
- setNewFiles(arFiles) {
637
- let index = 0;
638
- const maxAttachmentSize = PCore.getEnvironmentInfo().getMaxAttachmentSize() || 5;
639
- for (const file of arFiles) {
640
- file.mimeType = file.type;
641
- file.icon = this.utils.getIconFromFileType(file.type);
642
- file.ID = `${new Date().getTime()}I${index}`;
643
-
644
- if (!this.validateMaxSize(file, maxAttachmentSize)) {
645
- file.error = true;
646
- file.meta = this.pConn$.getLocalizedValue('File is too big. Max allowed size is 5MB.', '', '');
647
- } else if (!this.validateFileExtension(file, this.extensions$)) {
648
- file.error = true;
649
- file.meta = `${this.pConn$.getLocalizedValue('File has invalid extension. Allowed extensions are:', '', '')} ${this.extensions$.replaceAll(
650
- '.',
651
- ''
652
- )}`;
653
- }
654
- if (file.error) {
655
- const fieldName = (this.pConn$.getStateProps() as any).value;
656
- const context = this.pConn$.getContextName();
657
- PCore.getMessageManager().addMessages({
658
- // @ts-ignore
659
- messages: [
660
- {
661
- type: 'error',
662
- message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
663
- }
664
- ],
665
- property: fieldName,
666
- pageReference: this.pConn$.getPageReference(),
667
- context
668
- });
669
- }
670
- index++;
671
- }
672
-
673
- return [...arFiles];
674
449
  }
675
450
 
676
- validateMaxSize(fileObj, maxSizeInMB): boolean {
677
- const fileSize = (fileObj.size / 1048576).toFixed(2);
678
- return parseFloat(fileSize) < parseFloat(maxSizeInMB);
679
- }
680
-
681
- validateFileExtension = (fileObj, allowedExtensions) => {
682
- if (!allowedExtensions) {
683
- return true;
451
+ ngOnDestroy(): void {
452
+ if (this.angularPConnectData.unsubscribeFn) {
453
+ this.angularPConnectData.unsubscribeFn();
684
454
  }
685
- const allowedExtensionList = allowedExtensions
686
- .toLowerCase()
687
- .split(',')
688
- .map(item => item.replaceAll('.', '').trim());
689
- const extension = fileObj.name.split('.').pop().toLowerCase();
690
- return allowedExtensionList.includes(extension);
691
- };
692
455
 
693
- buildFilePropsFromResponse(respObj) {
694
- return {
695
- props: {
696
- meta: `${respObj.pyCategoryName}, ${respObj.pxCreateOperator}`,
697
- name: respObj.pyAttachName,
698
- icon: this.utils.getIconFromFileType(respObj.pyMimeFileExtension)
699
- },
700
- responseProps: {
701
- ...respObj
702
- }
703
- };
456
+ PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, this.caseID);
704
457
  }
705
458
  }