@pega/dx-component-builder-sdk 24.2.14 → 24.2.15

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 (127) hide show
  1. package/package.json +1 -1
  2. package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/index.tsx.mustache +1 -1
  3. package/src/tasks/create/templates/SDK-React/field/Picklist/index.tsx.mustache +7 -4
  4. package/src/tasks/create/templates/SDK-React/field/Picklist-RadioButtons/index.tsx.mustache +3 -2
  5. package/src/tasks/create/templates/SDK-React/widget/PAGE-CASE/index.tsx.mustache +1 -0
  6. package/tests/assets/sdk-r/components/create/custom-constellation/field/Pega_DXIL_MyTestText/demo.stories.tsx +0 -1
  7. package/tests/assets/sdk-r/components/create/override-sdk/designSystemExtension/FieldValueList/FieldValueList.tsx +2 -2
  8. package/tests/assets/sdk-r/components/create/override-sdk/designSystemExtension/RichTextEditor/RichTextEditor.tsx +4 -4
  9. package/tests/assets/sdk-r/components/create/override-sdk/field/CancelAlert/CancelAlert.tsx +1 -4
  10. package/tests/assets/sdk-r/components/create/override-sdk/field/Currency/Currency.tsx +8 -5
  11. package/tests/assets/sdk-r/components/create/override-sdk/field/Date/Date.tsx +5 -1
  12. package/tests/assets/sdk-r/components/create/override-sdk/field/DateTime/DateTime.tsx +13 -5
  13. package/tests/assets/sdk-r/components/create/override-sdk/field/Decimal/Decimal.tsx +7 -2
  14. package/tests/assets/sdk-r/components/create/override-sdk/field/Dropdown/Dropdown.tsx +34 -24
  15. package/tests/assets/sdk-r/components/create/override-sdk/field/Percentage/Percentage.tsx +6 -2
  16. package/tests/assets/sdk-r/components/create/override-sdk/field/RadioButtons/RadioButtons.tsx +3 -5
  17. package/tests/assets/sdk-r/components/create/override-sdk/field/ScalarList/ScalarList.tsx +1 -2
  18. package/tests/assets/sdk-r/components/create/override-sdk/field/Time/Time.tsx +1 -1
  19. package/tests/assets/sdk-r/components/create/override-sdk/field/UserReference/UserReference.tsx +1 -3
  20. package/tests/assets/sdk-r/components/create/override-sdk/infra/Assignment/Assignment.tsx +2 -6
  21. package/tests/assets/sdk-r/components/create/override-sdk/infra/DashboardFilter/DashboardFilter.tsx +2 -3
  22. package/tests/assets/sdk-r/components/create/override-sdk/infra/DashboardFilter/filterUtils.tsx +1 -3
  23. package/tests/assets/sdk-r/components/create/override-sdk/infra/DeferLoad/DeferLoad.tsx +5 -5
  24. package/tests/assets/sdk-r/components/create/override-sdk/infra/FlowContainer/FlowContainer.tsx +18 -108
  25. package/tests/assets/sdk-r/components/create/override-sdk/infra/FlowContainer/helpers.ts +1 -5
  26. package/tests/assets/sdk-r/components/create/override-sdk/infra/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +3 -1
  27. package/tests/assets/sdk-r/components/create/override-sdk/infra/MultiStep/MultiStep.tsx +1 -6
  28. package/tests/assets/sdk-r/components/create/override-sdk/infra/RootContainer/RootContainer.tsx +1 -1
  29. package/tests/assets/sdk-r/components/create/override-sdk/infra/SimpleView/helper.ts +1 -1
  30. package/tests/assets/sdk-r/components/create/override-sdk/template/AppShell/AppShell.tsx +6 -6
  31. package/tests/assets/sdk-r/components/create/override-sdk/template/CaseView/CaseView.tsx +5 -4
  32. package/tests/assets/sdk-r/components/create/override-sdk/template/Confirmation/Confirmation.tsx +1 -1
  33. package/tests/assets/sdk-r/components/create/override-sdk/template/DynamicTabs/DynamicTabs.tsx +0 -1
  34. package/tests/assets/sdk-r/components/create/override-sdk/template/FieldGroupTemplate/FieldGroupTemplate.tsx +10 -5
  35. package/tests/assets/sdk-r/components/create/override-sdk/template/ListView/ListView.tsx +13 -9
  36. package/tests/assets/sdk-r/components/create/override-sdk/template/ListView/hooks.ts +2 -0
  37. package/tests/assets/sdk-r/components/create/override-sdk/template/ListView/utils.ts +0 -1
  38. package/tests/assets/sdk-r/components/create/override-sdk/template/PromotedFilters/PromotedFilters.tsx +0 -1
  39. package/tests/assets/sdk-r/components/create/override-sdk/template/SimpleTable/SimpleTable.tsx +0 -2
  40. package/tests/assets/sdk-r/components/create/override-sdk/template/SimpleTableManual/SimpleTableManual.tsx +111 -94
  41. package/tests/assets/sdk-r/components/create/override-sdk/template/SimpleTableSelect/SimpleTableSelect.tsx +2 -4
  42. package/tests/assets/sdk-r/components/create/override-sdk/widget/Attachment/Attachment.css +1 -0
  43. package/tests/assets/sdk-r/components/create/override-sdk/widget/Attachment/Attachment.tsx +91 -73
  44. package/tests/assets/sdk-r/components/create/override-sdk/widget/FileUtility/FileUtility.tsx +1 -1
  45. package/tests/assets/sdk-r/components/create/override-sdk/widget/QuickCreate/QuickCreate.tsx +0 -1
  46. package/tests/assets/sdk-r/components/create/override-sdk/widget/SummaryItem/SummaryItem.tsx +1 -1
  47. package/tests/assets/sdk-r/components/create/override-sdk/widget/ToDo/ToDo.tsx +1 -1
  48. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyCurrency/demo.stories.tsx +0 -1
  49. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyDate/demo.stories.tsx +0 -16
  50. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyDateTime/demo.stories.tsx +0 -17
  51. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyDecimal/demo.stories.tsx +0 -1
  52. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyEmail/demo.stories.tsx +0 -1
  53. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyEmail/mock.ts +1 -0
  54. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +9 -20
  55. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyParagraph/demo.stories.tsx +0 -1
  56. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyPercentage/demo.stories.tsx +0 -1
  57. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyPercentage/mock.ts +1 -0
  58. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyPhone/demo.stories.tsx +1 -2
  59. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyPicklist/demo.stories.tsx +0 -1
  60. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyRadiobuttons/demo.stories.tsx +0 -1
  61. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MySearchbox/demo.stories.tsx +0 -1
  62. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyText/demo.stories.tsx +0 -1
  63. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyTextInput/demo.stories.tsx +0 -1
  64. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyTimeOfDay/demo.stories.tsx +0 -1
  65. package/tests/assets/sdk-r/components/createAll/custom-constellation/field/Pega_DXIL_MyURL/demo.stories.tsx +0 -1
  66. package/tests/assets/sdk-r/components/createAll/custom-constellation/template/Pega_DXIL_MyDetails/demo.stories.tsx +10 -0
  67. package/tests/assets/sdk-r/components/createAll/custom-constellation/template/Pega_DXIL_MyPage/demo.stories.tsx +1 -13
  68. package/tests/assets/sdk-r/components/createAll/custom-constellation/widget/Pega_DXIL_MyCaseWidget/demo.stories.tsx +10 -32
  69. package/tests/assets/sdk-r/components/createAll/custom-constellation/widget/Pega_DXIL_MyPageCaseWidget/demo.stories.tsx +10 -22
  70. package/tests/assets/sdk-r/components/createAll/custom-constellation/widget/Pega_DXIL_MyPageWidget/demo.stories.tsx +10 -21
  71. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyCurrency/demo.stories.tsx +0 -14
  72. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyDate/demo.stories.tsx +0 -24
  73. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyDateTime/demo.stories.tsx +0 -24
  74. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyDecimal/demo.stories.tsx +0 -14
  75. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +2 -6
  76. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyIconButtonURL/index.tsx +1 -1
  77. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyPercentage/demo.stories.tsx +0 -14
  78. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyPicklist/index.tsx +7 -4
  79. package/tests/assets/sdk-r/components/createAll/custom-sdk/field/Pega_DXIL_MyRadiobuttons/index.tsx +3 -2
  80. package/tests/assets/sdk-r/components/createAll/custom-sdk/template/Pega_DXIL_MyDetails/demo.stories.tsx +8 -28
  81. package/tests/assets/sdk-r/components/createAll/custom-sdk/template/Pega_DXIL_MyForm/demo.stories.tsx +10 -16
  82. package/tests/assets/sdk-r/components/createAll/custom-sdk/template/Pega_DXIL_MyTwoColumnDetails/demo.stories.tsx +8 -28
  83. package/tests/assets/sdk-r/components/createAll/custom-sdk/widget/Pega_DXIL_MyCaseWidget/demo.stories.tsx +10 -20
  84. package/tests/assets/sdk-r/components/createAll/custom-sdk/widget/Pega_DXIL_MyPageCaseWidget/demo.stories.tsx +10 -20
  85. package/tests/assets/sdk-r/components/createAll/custom-sdk/widget/Pega_DXIL_MyPageCaseWidget/index.tsx +1 -0
  86. package/tests/assets/sdk-r/components/createAll/custom-sdk/widget/Pega_DXIL_MyPageWidget/demo.stories.tsx +9 -19
  87. package/tests/assets/sdk-r/components/createAll/override-sdk/designSystemExtension/FieldValueList/FieldValueList.tsx +2 -2
  88. package/tests/assets/sdk-r/components/createAll/override-sdk/designSystemExtension/RichTextEditor/RichTextEditor.tsx +4 -4
  89. package/tests/assets/sdk-r/components/createAll/override-sdk/field/CancelAlert/CancelAlert.tsx +1 -4
  90. package/tests/assets/sdk-r/components/createAll/override-sdk/field/Currency/Currency.tsx +8 -5
  91. package/tests/assets/sdk-r/components/createAll/override-sdk/field/Date/Date.tsx +5 -1
  92. package/tests/assets/sdk-r/components/createAll/override-sdk/field/DateTime/DateTime.tsx +13 -5
  93. package/tests/assets/sdk-r/components/createAll/override-sdk/field/Decimal/Decimal.tsx +7 -2
  94. package/tests/assets/sdk-r/components/createAll/override-sdk/field/Dropdown/Dropdown.tsx +34 -24
  95. package/tests/assets/sdk-r/components/createAll/override-sdk/field/Percentage/Percentage.tsx +6 -2
  96. package/tests/assets/sdk-r/components/createAll/override-sdk/field/RadioButtons/RadioButtons.tsx +3 -5
  97. package/tests/assets/sdk-r/components/createAll/override-sdk/field/ScalarList/ScalarList.tsx +1 -2
  98. package/tests/assets/sdk-r/components/createAll/override-sdk/field/Time/Time.tsx +1 -1
  99. package/tests/assets/sdk-r/components/createAll/override-sdk/field/UserReference/UserReference.tsx +1 -3
  100. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/Assignment/Assignment.tsx +2 -6
  101. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/DashboardFilter/DashboardFilter.tsx +2 -3
  102. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/DashboardFilter/filterUtils.tsx +1 -3
  103. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/DeferLoad/DeferLoad.tsx +5 -5
  104. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/FlowContainer/FlowContainer.tsx +18 -108
  105. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/FlowContainer/helpers.ts +1 -5
  106. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +3 -1
  107. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/MultiStep/MultiStep.tsx +1 -6
  108. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/RootContainer/RootContainer.tsx +1 -1
  109. package/tests/assets/sdk-r/components/createAll/override-sdk/infra/SimpleView/helper.ts +1 -1
  110. package/tests/assets/sdk-r/components/createAll/override-sdk/template/AppShell/AppShell.tsx +6 -6
  111. package/tests/assets/sdk-r/components/createAll/override-sdk/template/CaseView/CaseView.tsx +5 -4
  112. package/tests/assets/sdk-r/components/createAll/override-sdk/template/Confirmation/Confirmation.tsx +1 -1
  113. package/tests/assets/sdk-r/components/createAll/override-sdk/template/DynamicTabs/DynamicTabs.tsx +0 -1
  114. package/tests/assets/sdk-r/components/createAll/override-sdk/template/FieldGroupTemplate/FieldGroupTemplate.tsx +10 -5
  115. package/tests/assets/sdk-r/components/createAll/override-sdk/template/ListView/ListView.tsx +13 -9
  116. package/tests/assets/sdk-r/components/createAll/override-sdk/template/ListView/hooks.ts +2 -0
  117. package/tests/assets/sdk-r/components/createAll/override-sdk/template/ListView/utils.ts +0 -1
  118. package/tests/assets/sdk-r/components/createAll/override-sdk/template/PromotedFilters/PromotedFilters.tsx +0 -1
  119. package/tests/assets/sdk-r/components/createAll/override-sdk/template/SimpleTable/SimpleTable.tsx +0 -2
  120. package/tests/assets/sdk-r/components/createAll/override-sdk/template/SimpleTableManual/SimpleTableManual.tsx +111 -94
  121. package/tests/assets/sdk-r/components/createAll/override-sdk/template/SimpleTableSelect/SimpleTableSelect.tsx +2 -4
  122. package/tests/assets/sdk-r/components/createAll/override-sdk/widget/Attachment/Attachment.css +1 -0
  123. package/tests/assets/sdk-r/components/createAll/override-sdk/widget/Attachment/Attachment.tsx +91 -73
  124. package/tests/assets/sdk-r/components/createAll/override-sdk/widget/FileUtility/FileUtility.tsx +1 -1
  125. package/tests/assets/sdk-r/components/createAll/override-sdk/widget/QuickCreate/QuickCreate.tsx +0 -1
  126. package/tests/assets/sdk-r/components/createAll/override-sdk/widget/SummaryItem/SummaryItem.tsx +1 -1
  127. package/tests/assets/sdk-r/components/createAll/override-sdk/widget/ToDo/ToDo.tsx +1 -1
@@ -1,12 +1,12 @@
1
1
  /* eslint-disable react/jsx-boolean-value */
2
2
  /* eslint-disable react/no-array-index-key */
3
3
  /* eslint-disable no-nested-ternary */
4
- import { useState, useEffect, useCallback } from 'react';
4
+ import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
5
5
  import { CircularProgress, IconButton, Menu, MenuItem, Button } from '@mui/material';
6
6
  import MoreVertIcon from '@mui/icons-material/MoreVert';
7
- import download from 'downloadjs';
8
7
 
9
- import { buildFilePropsFromResponse, getIconFromFileType, validateMaxSize } from '@pega/react-sdk-components/lib/components/helpers/attachmentHelpers';
8
+ import { getIconFromFileType, isFileUploadedToServer, useFileDownload, validateMaxSize } from '@pega/react-sdk-components/lib/components/helpers/attachmentHelpers';
9
+
10
10
  import { Utils } from '@pega/react-sdk-components/lib/components/helpers/utils';
11
11
  import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
12
12
 
@@ -19,7 +19,9 @@ interface AttachmentProps extends Omit<PConnFieldProps, 'value'> {
19
19
  extensions: string;
20
20
  }
21
21
 
22
- const getAttachmentKey = (name = '') => (name ? `attachmentsList.${name}` : 'attachmentsList');
22
+ const getAttachmentKey = (name, embeddedReference) => {
23
+ return `attachmentsList${embeddedReference}.${name}`;
24
+ };
23
25
 
24
26
  const getCurrentAttachmentsList = (key, context) => {
25
27
  return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
@@ -33,95 +35,101 @@ const updateAttachmentState = (pConn, key, attachments) => {
33
35
  };
34
36
 
35
37
  export default function Attachment(props: AttachmentProps) {
36
- const { value, getPConnect, label, validatemessage, allowMultiple, extensions, displayMode } = props;
38
+ const { value, getPConnect, label, validatemessage, allowMultiple, extensions, displayMode, helperText } = props;
37
39
  /* this is a temporary fix because required is supposed to be passed as a boolean and NOT as a string */
38
40
  let { required, disabled } = props;
39
41
  [required, disabled] = [required, disabled].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
40
42
  const pConn = getPConnect();
43
+
44
+ const actionSequencer = useMemo(() => PCore.getActionsSequencer(), []);
41
45
  const caseID = PCore.getStoreValue('.pyID', 'caseInfo.content', pConn.getContextName());
42
46
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
43
47
  const localeCategory = 'CosmosFields';
44
48
  const uploadMultipleFilesLabel = localizedVal('file_upload_text_multiple', localeCategory);
45
49
  const uploadSingleFileLabel = localizedVal('file_upload_text_one', localeCategory);
46
- let categoryName = '';
47
- if (value && value.pyCategoryName) {
48
- categoryName = value.pyCategoryName;
49
- }
50
50
  const deleteIcon = Utils.getImageSrc('trash', Utils.getSDKStaticConentUrl());
51
51
  const srcImg = Utils.getImageSrc('document-doc', Utils.getSDKStaticConentUrl());
52
52
  let valueRef = (pConn.getStateProps() as any).value;
53
53
  valueRef = valueRef.indexOf('.') === 0 ? valueRef.substring(1) : valueRef;
54
- const [anchorEl, setAnchorEl] = useState(null);
55
- const open = Boolean(anchorEl);
56
- const [files, setFiles] = useState<any[]>(() =>
57
- value?.pxResults && +value.pyCount > 0 ? value.pxResults.map(f => buildFilePropsFromResponse(f)) : []
58
- );
54
+ const [menuAnchorEl, setMenuAnchorEl] = useState(null);
55
+ const [menuOpenIndex, setMenuOpenIndex] = useState<number | null>(null);
56
+
57
+ const rawValue = pConn.getComponentConfig().value;
58
+ const isAttachmentAnnotationPresent = typeof rawValue === 'object' ? false : rawValue?.includes('@ATTACHMENT');
59
+ const { hasUploadedFiles, attachments, categoryName } = isAttachmentAnnotationPresent
60
+ ? value
61
+ : PCore.getAttachmentUtils().prepareAttachmentData(value);
62
+
63
+ const fileInputRef = useRef<HTMLInputElement>(null);
64
+ const [files, setFiles] = useState<any[]>(attachments);
59
65
  const [filesWithError, setFilesWithError] = useState<any[]>([]);
60
66
  const [toggleUploadBegin, setToggleUploadBegin] = useState(false);
61
67
 
68
+ const context = pConn.getContextName();
69
+ const onFileDownload = useFileDownload(context);
70
+
71
+ let embeddedProperty = pConn
72
+ .getPageReference()
73
+ .replace(PCore.getConstants().CASE_INFO.CASE_INFO_CONTENT, '')
74
+ .replace(PCore.getConstants().DATA_INFO.DATA_INFO_CONTENT, '');
75
+
76
+ if (valueRef?.indexOf('.') > 0) {
77
+ embeddedProperty = valueRef.substring(0, valueRef.indexOf('.') + 1);
78
+ }
79
+
62
80
  const resetAttachmentStoredState = () => {
63
- PCore.getStateUtils().updateState(pConn.getContextName(), getAttachmentKey(valueRef), undefined, {
81
+ PCore.getStateUtils().updateState(pConn.getContextName(), getAttachmentKey(valueRef, embeddedProperty), undefined, {
64
82
  pageReference: 'context_data',
65
83
  isArrayDeepMerge: false
66
84
  });
67
85
  };
68
86
 
69
- const fileDownload = (data, fileName, ext) => {
70
- const fileData = ext ? `${fileName}.${ext}` : fileName;
71
- download(atob(data), fileData);
72
- };
73
-
74
- const downloadFile = (fileObj: any) => {
75
- setAnchorEl(null);
76
- PCore.getAttachmentUtils()
77
- // @ts-ignore - 3rd parameter "responseEncoding" should be optional
78
- .downloadAttachment(fileObj.pzInsKey, pConn.getContextName())
79
- .then((content: any) => {
80
- const extension = fileObj.pyAttachName.split('.').pop();
81
- fileDownload(content.data, fileObj.pyFileName, extension);
82
- })
83
- .catch(() => {});
84
- };
85
-
86
87
  const deleteFile = useCallback(
87
88
  file => {
88
- setAnchorEl(null);
89
+ setMenuAnchorEl(null);
90
+ setMenuOpenIndex(null);
91
+
92
+ // reset the file input so that it will allow re-uploading the same file after deletion
93
+ if (fileInputRef.current) {
94
+ fileInputRef.current.value = ''; // Reset the input
95
+ }
96
+
89
97
  let attachmentsList: any[] = [];
90
- let currentAttachmentList = getCurrentAttachmentsList(getAttachmentKey(valueRef), pConn.getContextName());
98
+ let currentAttachmentList = getCurrentAttachmentsList(getAttachmentKey(valueRef, embeddedProperty), pConn.getContextName());
91
99
 
92
100
  // If file to be deleted is the one added in previous stage i.e. for which a file instance is created in server
93
101
  // no need to filter currentAttachmentList as we will get another entry of file in redux with delete & label
94
- // eslint-disable-next-line no-unsafe-optional-chaining
95
- if (value && value?.pxResults && +value?.pyCount > 0 && file.responseProps && file?.responseProps?.pzInsKey !== 'temp') {
96
- const updatedAttachments = files.map(f => {
97
- if (f.responseProps && f.responseProps.pzInsKey === file.responseProps.pzInsKey) {
102
+ if (hasUploadedFiles && isFileUploadedToServer(file)) {
103
+ // Use currentAttachmentList (fresh from store) instead of files (stale closure)
104
+ // to preserve delete markers set by previous deletions in the same session
105
+ const updatedAttachments = currentAttachmentList.map(f => {
106
+ if (f.responseProps && f.responseProps.ID === file.responseProps.ID) {
98
107
  return { ...f, delete: true, label: valueRef };
99
108
  }
100
109
  return f;
101
110
  });
102
111
 
103
112
  // updating the redux store to help form-handler in passing the data to delete the file from server
104
- updateAttachmentState(pConn, getAttachmentKey(valueRef), [...updatedAttachments]);
113
+ updateAttachmentState(pConn, getAttachmentKey(valueRef, embeddedProperty), [...updatedAttachments]);
105
114
  setFiles(current => {
106
115
  const newlyAddedFiles = current.filter(f => !!f.ID);
107
- const filesPostDelete = current.filter(
108
- f => f.responseProps?.pzInsKey !== 'temp' && f.responseProps?.pzInsKey !== file.responseProps?.pzInsKey
109
- );
116
+ const filesPostDelete = current.filter(f => isFileUploadedToServer(f) && f.responseProps?.ID !== file.responseProps?.ID);
110
117
  attachmentsList = [...filesPostDelete, ...newlyAddedFiles];
111
118
  return attachmentsList;
112
119
  });
113
120
  } // if the file being deleted is the added in this stage i.e. whose data is not yet created in server
114
121
  else {
115
122
  // filter newly added files in this stage, later the updated current stage files will be added to redux once files state is updated in below setFiles()
116
- currentAttachmentList = currentAttachmentList.filter(f => f.label !== valueRef);
117
- setFiles(current => {
118
- attachmentsList = current.filter(f => f.ID !== file.ID);
119
- return attachmentsList;
120
- });
121
- updateAttachmentState(pConn, getAttachmentKey(valueRef), [...currentAttachmentList, ...attachmentsList]);
123
+ currentAttachmentList = currentAttachmentList.filter(f => !f.props.error && (f.delete || f.label !== valueRef));
124
+ setFiles(current => current.filter(f => f.ID !== file.ID));
125
+ updateAttachmentState(pConn, getAttachmentKey(valueRef, embeddedProperty), [...currentAttachmentList, ...attachmentsList]);
122
126
  if (file.inProgress) {
123
127
  // @ts-ignore - 3rd parameter "responseEncoding" should be optional
124
128
  PCore.getAttachmentUtils().cancelRequest(file.ID, pConn.getContextName());
129
+ actionSequencer.deRegisterBlockingAction(pConn.getContextName()).catch(error => {
130
+ // eslint-disable-next-line no-console
131
+ console.log(error);
132
+ });
125
133
  }
126
134
  }
127
135
 
@@ -130,7 +138,7 @@ export default function Attachment(props: AttachmentProps) {
130
138
  return prevFilesWithError.filter(f => f.ID !== file.ID);
131
139
  });
132
140
  },
133
- [pConn, value, valueRef, filesWithError]
141
+ [valueRef, pConn, hasUploadedFiles, filesWithError, hasUploadedFiles, actionSequencer]
134
142
  );
135
143
 
136
144
  const onUploadProgress = () => {};
@@ -152,14 +160,11 @@ export default function Attachment(props: AttachmentProps) {
152
160
  f.props.name = pConn.getLocalizedValue('Unable to upload file', '', '');
153
161
  f.inProgress = false;
154
162
  const fieldName = (pConn.getStateProps() as any).value;
155
- const context = pConn.getContextName();
156
163
  // set errors to property to block submit even on errors in file upload
157
164
  PCore.getMessageManager().addMessages({
158
- // @ts-ignore
159
165
  messages: [
160
166
  {
161
167
  type: 'error',
162
- // @ts-ignore - Type '{ type: string; message: string; }' is not assignable to type 'MessagesConfigObject'.
163
168
  message: pConn.getLocalizedValue('Error with one or more files', '', '')
164
169
  }
165
170
  ],
@@ -191,8 +196,6 @@ export default function Attachment(props: AttachmentProps) {
191
196
 
192
197
  const clearFieldErrorMessages = () => {
193
198
  const fieldName = (pConn.getStateProps() as any).value;
194
- const context = pConn.getContextName();
195
- // @ts-ignore
196
199
  PCore.getMessageManager().clearMessages({
197
200
  type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
198
201
  property: fieldName,
@@ -229,13 +232,10 @@ export default function Attachment(props: AttachmentProps) {
229
232
  }
230
233
  if (f.props.error) {
231
234
  const fieldName = (pConn.getStateProps() as any).value;
232
- const context = pConn.getContextName();
233
235
  PCore.getMessageManager().addMessages({
234
- // @ts-ignore
235
236
  messages: [
236
237
  {
237
238
  type: 'error',
238
- // @ts-ignore - Type '{ type: string; message: string; }' is not assignable to type 'MessagesConfigObject'.
239
239
  message: pConn.getLocalizedValue('Error with one or more files', '', '')
240
240
  }
241
241
  ],
@@ -260,7 +260,7 @@ export default function Attachment(props: AttachmentProps) {
260
260
  .filter(e => {
261
261
  const isFileUploaded = e.props && e.props.progress === 100;
262
262
  const fileHasError = e.props && e.props.error;
263
- const isFileUploadedinLastStep = e.responseProps && e.responseProps.pzInsKey;
263
+ const isFileUploadedinLastStep = e.responseProps && (e.responseProps.pzInsKey || e.responseProps.ID);
264
264
  return !isFileUploaded && !fileHasError && !isFileUploadedinLastStep;
265
265
  })
266
266
  .map(f =>
@@ -291,7 +291,7 @@ export default function Attachment(props: AttachmentProps) {
291
291
  f.label = valueRef;
292
292
  f.category = categoryName;
293
293
  f.responseProps = {
294
- pzInsKey: 'temp',
294
+ ID: 'temp',
295
295
  pyAttachName: f.props.name
296
296
  };
297
297
  }
@@ -320,12 +320,12 @@ export default function Attachment(props: AttachmentProps) {
320
320
 
321
321
  useEffect(() => {
322
322
  if (files.length > 0 && displayMode !== 'DISPLAY_ONLY') {
323
- const currentAttachmentList = getCurrentAttachmentsList(getAttachmentKey(valueRef), pConn.getContextName());
323
+ const currentAttachmentList = getCurrentAttachmentsList(getAttachmentKey(valueRef, embeddedProperty), pConn.getContextName());
324
324
  // block duplicate files to redux store when added 1 after another to prevent multiple duplicates being added to the case on submit
325
325
  const tempFiles = files.filter(f => currentAttachmentList.findIndex(fr => fr.ID === f.ID) === -1 && !f.inProgress && f.responseProps);
326
326
 
327
327
  const updatedAttList = [...currentAttachmentList, ...tempFiles];
328
- updateAttachmentState(pConn, getAttachmentKey(valueRef), updatedAttList);
328
+ updateAttachmentState(pConn, getAttachmentKey(valueRef, embeddedProperty), updatedAttList);
329
329
  }
330
330
  }, [files]);
331
331
 
@@ -336,7 +336,7 @@ export default function Attachment(props: AttachmentProps) {
336
336
  }, [filesWithError]);
337
337
 
338
338
  useEffect(() => {
339
- let tempUploadedFiles = getCurrentAttachmentsList(getAttachmentKey(valueRef), pConn.getContextName());
339
+ let tempUploadedFiles = getCurrentAttachmentsList(getAttachmentKey(valueRef, embeddedProperty), pConn.getContextName());
340
340
  tempUploadedFiles = tempUploadedFiles.filter(f => f.label === valueRef);
341
341
  setFiles(current => {
342
342
  return [
@@ -354,18 +354,25 @@ export default function Attachment(props: AttachmentProps) {
354
354
  ...tempUploadedFiles
355
355
  ];
356
356
  });
357
- PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, resetAttachmentStoredState, caseID);
357
+ if (displayMode !== 'DISPLAY_ONLY') {
358
+ PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, resetAttachmentStoredState, caseID);
359
+ }
358
360
  return () => {
359
- PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, caseID);
361
+ if (displayMode !== 'DISPLAY_ONLY') {
362
+ PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, caseID);
363
+ }
364
+ resetAttachmentStoredState();
360
365
  };
361
366
  }, []);
362
367
 
363
- const handleClick = event => {
364
- setAnchorEl(event.currentTarget);
368
+ const handleClick = (event, index) => {
369
+ setMenuAnchorEl(event.currentTarget);
370
+ setMenuOpenIndex(index);
365
371
  };
366
372
 
367
373
  const handleClose = () => {
368
- setAnchorEl(null);
374
+ setMenuAnchorEl(null);
375
+ setMenuOpenIndex(null);
369
376
  };
370
377
 
371
378
  const content = (
@@ -428,19 +435,30 @@ export default function Attachment(props: AttachmentProps) {
428
435
  <div>
429
436
  <IconButton
430
437
  id='setting-button'
431
- aria-controls={open ? 'file-menu' : undefined}
432
- aria-expanded={open ? 'true' : undefined}
438
+ aria-controls={menuOpenIndex === index ? 'file-menu' : undefined}
439
+ aria-expanded={menuOpenIndex === index ? 'true' : undefined}
433
440
  aria-haspopup='true'
434
- onClick={handleClick}
441
+ onClick={event => handleClick(event, index)}
435
442
  size='large'
436
443
  >
437
444
  <MoreVertIcon />
438
445
  </IconButton>
439
- <Menu style={{ marginTop: '3rem' }} id='file-menu' anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
446
+ <Menu
447
+ id='file-menu'
448
+ anchorEl={menuAnchorEl}
449
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
450
+ transformOrigin={{ vertical: 'top', horizontal: 'right' }}
451
+ keepMounted
452
+ open={menuOpenIndex === index}
453
+ onClose={handleClose}
454
+ >
440
455
  <MenuItem
441
456
  style={{ fontSize: '14px' }}
442
457
  key='download'
443
- onClick={() => downloadFile(item.responseProps ? item.responseProps : {})}
458
+ onClick={() => {
459
+ handleClose();
460
+ onFileDownload(item.responseProps ? item.responseProps : {});
461
+ }}
444
462
  >
445
463
  Download
446
464
  </MenuItem>
@@ -461,7 +479,7 @@ export default function Attachment(props: AttachmentProps) {
461
479
  <div className='file-upload-container'>
462
480
  <span className={`label ${required ? 'file-label' : ''}`}>{label}</span>
463
481
  {((files.length === 0 && allowMultiple !== 'true') || allowMultiple === 'true') && <section>{content}</section>}
464
- {validatemessage !== '' ? <span className='file-error'>{validatemessage}</span> : ''}
482
+ {validatemessage !== '' ? <span className='file-error'>{validatemessage}</span> : <span style={{ fontSize: '14px' }}>{helperText}</span>}
465
483
  {files && files.length > 0 && <section>{fileDisplay}</section>}
466
484
  </div>
467
485
  );
@@ -512,7 +512,7 @@ export default function FileUtility(props: FileUtilityProps) {
512
512
  >
513
513
  <MoreVertIcon />
514
514
  </IconButton>
515
- <Menu style={{ marginTop: '3rem' }} id='simple-menu' anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
515
+ <Menu id='simple-menu' anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
516
516
  <MenuItem style={{ fontSize: '14px' }} onClick={onAddFilesClick}>
517
517
  {thePConn.getLocalizedValue('Add files', '', '')}
518
518
  </MenuItem>{' '}
@@ -35,7 +35,6 @@ export default function QuickCreate(props: QuickCreateProps) {
35
35
  const defaultCases: any = [];
36
36
  const envInfo = PCore.getEnvironmentInfo();
37
37
  if (envInfo?.environmentInfoObject?.pyCaseTypeList) {
38
- // @ts-ignore - Property 'forEach' does not exist on type 'string'
39
38
  envInfo.environmentInfoObject.pyCaseTypeList.forEach(casetype => {
40
39
  if (casetype.pyWorkTypeName && casetype.pyWorkTypeImplementationClassName) {
41
40
  defaultCases.push({
@@ -73,7 +73,7 @@ export default function SummaryItem(props: SummaryItemProps) {
73
73
  >
74
74
  <MoreVertIcon />
75
75
  </IconButton>
76
- <Menu style={{ marginTop: '3rem' }} id='file-menu' anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
76
+ <Menu id='file-menu' anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
77
77
  {item.actions &&
78
78
  item.actions.map(option => (
79
79
  <MenuItem style={{ fontSize: '14px' }} key={option.id || option.text} onClick={option.onClick}>
@@ -129,7 +129,7 @@ export default function ToDo(props: ToDoProps) {
129
129
  const CONSTS = PCore.getConstants();
130
130
 
131
131
  const bLogging = true;
132
- const currentUser = PCore.getEnvironmentInfo().getOperatorName();
132
+ const currentUser = PCore.getEnvironmentInfo().getOperatorName() ?? '';
133
133
  const currentUserInitials = Utils.getInitials(currentUser);
134
134
  const assignmentsSource = datasource?.source || myWorkList?.source;
135
135
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import { configProps, fieldMetadata, stateProps } from './mock';
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
  import { configProps, stateProps } from './mock';
6
5
  import PegaDxilMyDate from './index';
@@ -14,21 +13,6 @@ const meta: Meta<typeof PegaDxilMyDate> = {
14
13
  export default meta;
15
14
  type Story = StoryObj<typeof PegaDxilMyDate>;
16
15
 
17
- if (!window.PCore) {
18
- window.PCore = {};
19
- }
20
-
21
- window.PCore.getEnvironmentInfo = () => {
22
- return {
23
- getTimeZone: () => {
24
- return '';
25
- },
26
- getLocale: () => {
27
- return 'en-GB';
28
- }
29
- };
30
- };
31
-
32
16
  export const BasePegaDxilMyDate: Story = args => {
33
17
  const props = {
34
18
  value: configProps.value,
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable react/jsx-no-useless-fragment */
2
- // @ts-nocheck
3
2
  import type { Meta, StoryObj } from '@storybook/react';
4
3
  import { configProps, stateProps } from './mock';
5
4
  import PegaDxilMyDateTime from './index';
@@ -13,22 +12,6 @@ const meta: Meta<typeof PegaDxilMyDateTime> = {
13
12
  export default meta;
14
13
  type Story = StoryObj<typeof PegaDxilMyDateTime>;
15
14
 
16
-
17
- if (!window.PCore) {
18
- window.PCore = {};
19
- }
20
-
21
- window.PCore.getEnvironmentInfo = () => {
22
- return {
23
- getTimeZone: () => {
24
- return '';
25
- },
26
- getLocale: () => {
27
- return 'en-GB';
28
- }
29
- };
30
- };
31
-
32
15
  export const BasePegaDxilMyDateTime: Story = args => {
33
16
  const props = {
34
17
  value: configProps.value,
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import { configProps, fieldMetadata, stateProps } from './mock';
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import PegaDxilMyEmail from './index';
@@ -12,6 +12,7 @@ export const configProps = {
12
12
  readOnly: false,
13
13
  required: false,
14
14
  disabled: false,
15
+ variant: '',
15
16
  status: '',
16
17
  validatemessage: ''
17
18
  };
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import PegaDxilMyIconButtonUrl from './index';
@@ -15,10 +14,6 @@ const meta: Meta<typeof PegaDxilMyIconButtonUrl> = {
15
14
  export default meta;
16
15
  type Story = StoryObj<typeof PegaDxilMyIconButtonUrl>;
17
16
 
18
- if (!window.PCore) {
19
- window.PCore = {};
20
- }
21
-
22
17
  const statelistData = {
23
18
  data: [
24
19
  {
@@ -36,23 +31,17 @@ const statelistData = {
36
31
  ]
37
32
  };
38
33
 
39
- export const BasePegaDxilMyIconButtonUrl: Story = args => {
40
-
41
- window.PCore.getDataPageUtils = () => {
42
- return {
43
- getData: () => {
44
- return new Promise(resolve => {
45
- resolve(statelistData);
46
- });
47
- },
48
- getDataAsync: () => {
49
- return new Promise(resolve => {
50
- resolve(statelistData);
51
- });
52
- }
53
- };
34
+ window.PCore.getDataPageUtils = (): any => {
35
+ return {
36
+ getDataAsync: () => {
37
+ return new Promise(resolve => {
38
+ resolve(statelistData);
39
+ });
40
+ }
54
41
  };
42
+ };
55
43
 
44
+ export const BasePegaDxilMyIconButtonUrl: Story = args => {
56
45
  const props = {
57
46
  countryCode: configProps.countryCode,
58
47
  getPConnect: () => {
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import PegaDxilMyParagraph from './index';
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import { configProps, stateProps, fieldMetadata } from './mock';
@@ -4,6 +4,7 @@ export const configProps = {
4
4
  value: '',
5
5
  label: 'Percentage Sample',
6
6
  showGroupSeparators: true,
7
+ placeholder: '',
7
8
  helperText: 'Percentage Helper Text',
8
9
  testId: 'percentage-12345678',
9
10
  hasSuggestions: false,
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import PegaDxilMyPhone from './index';
@@ -47,7 +46,7 @@ export const BasePegaDxilMyPhone: Story = args => {
47
46
  };
48
47
 
49
48
  BasePegaDxilMyPhone.args = {
50
- datasource: configProps.datasource,
49
+ datasource: configProps.datasource as any,
51
50
  label: configProps.label,
52
51
  helperText: configProps.helperText,
53
52
  placeholder: configProps.placeholder,
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import { useState } from 'react';
5
4
  import type { Meta, StoryObj } from '@storybook/react';
6
5
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import { useState } from 'react';
5
4
  import type { Meta, StoryObj } from '@storybook/react';
6
5
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import { useState } from 'react';
5
4
  import type { Meta, StoryObj } from '@storybook/react';
6
5
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import { useState } from 'react';
5
4
  import type { Meta, StoryObj } from '@storybook/react';
6
5
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import PegaDxilMyTextInput from './index';
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable react/jsx-no-useless-fragment */
2
- // @ts-nocheck
3
2
  import type { Meta, StoryObj } from '@storybook/react';
4
3
  import { configProps, stateProps } from './mock';
5
4
  import PegaDxilMyTimeOfDay from './index';
@@ -1,6 +1,5 @@
1
1
 
2
2
  /* eslint-disable react/jsx-no-useless-fragment */
3
- // @ts-nocheck
4
3
  import type { Meta, StoryObj } from '@storybook/react';
5
4
 
6
5
  import PegaDxilMyUrl from './index';
@@ -8,6 +8,16 @@ import { pyReviewRaw, pyReviewResolved, regionChildrenResolved, operatorDetails,
8
8
  import StatusWorkRenderer from './StatusWork';
9
9
  import Operator from './Operator';
10
10
 
11
+ window.PCore.getUserApi = (): any => {
12
+ return {
13
+ getOperatorDetails: () => {
14
+ return new Promise(resolve => {
15
+ resolve(operatorDetails);
16
+ });
17
+ }
18
+ };
19
+ };
20
+
11
21
  const meta: Meta<typeof PegaDxilMyDetails> = {
12
22
  title: 'PegaDxilMyDetails',
13
23
  component: PegaDxilMyDetails,