@rh-support/troubleshoot 2.6.299 → 2.6.300

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 (178) hide show
  1. package/lib/esm/components/AccountInfo/AccountSelector.d.ts.map +1 -1
  2. package/lib/esm/components/AccountInfo/AccountSelector.js +40 -28
  3. package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.d.ts.map +1 -1
  4. package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.js +19 -46
  5. package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
  6. package/lib/esm/components/CaseEditView/Case.js +17 -49
  7. package/lib/esm/components/CaseEditView/CaseDetailsAside.d.ts.map +1 -1
  8. package/lib/esm/components/CaseEditView/CaseDetailsAside.js +8 -25
  9. package/lib/esm/components/CaseEditView/CaseDetailsTabs.d.ts.map +1 -1
  10. package/lib/esm/components/CaseEditView/CaseDetailsTabs.js +17 -31
  11. package/lib/esm/components/CaseEditView/CaseOverview/CaseStatus.d.ts +2 -1
  12. package/lib/esm/components/CaseEditView/CaseOverview/CaseStatus.d.ts.map +1 -1
  13. package/lib/esm/components/CaseEditView/CaseOverview/CaseStatus.js +6 -8
  14. package/lib/esm/components/CaseEditView/CaseOverview/index.d.ts.map +1 -1
  15. package/lib/esm/components/CaseEditView/CaseOverview/index.js +28 -39
  16. package/lib/esm/components/CaseEditView/ConfirmationModals/ReopenCaseModal.d.ts +3 -1
  17. package/lib/esm/components/CaseEditView/ConfirmationModals/ReopenCaseModal.d.ts.map +1 -1
  18. package/lib/esm/components/CaseEditView/ConfirmationModals/ReopenCaseModal.js +4 -3
  19. package/lib/esm/components/CaseEditView/RequestRemoteSession/ESSRemoteSessionModal.d.ts.map +1 -1
  20. package/lib/esm/components/CaseEditView/RequestRemoteSession/ESSRemoteSessionModal.js +7 -4
  21. package/lib/esm/components/CaseEditView/RequestRemoteSession/NewEssTermsModal.d.ts.map +1 -1
  22. package/lib/esm/components/CaseEditView/RequestRemoteSession/NewEssTermsModal.js +36 -13
  23. package/lib/esm/components/CaseEditView/RequestRemoteSession/RemoteSessionAgreementModal.d.ts.map +1 -1
  24. package/lib/esm/components/CaseEditView/RequestRemoteSession/RemoteSessionAgreementModal.js +33 -11
  25. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseContactPhoneNumber.d.ts.map +1 -1
  26. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseContactPhoneNumber.js +34 -38
  27. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.d.ts.map +1 -1
  28. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.js +9 -9
  29. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.d.ts.map +1 -1
  30. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.js +59 -19
  31. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/Summary.d.ts.map +1 -1
  32. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/Summary.js +9 -16
  33. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts +2 -4
  34. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts.map +1 -1
  35. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.js +148 -110
  36. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts +2 -6
  37. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
  38. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +241 -147
  39. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.d.ts.map +1 -1
  40. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.js +3 -5
  41. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/CaseHistory.d.ts.map +1 -1
  42. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/CaseHistory.js +1 -3
  43. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.css +4 -4
  44. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.d.ts +3 -35
  45. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.d.ts.map +1 -1
  46. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.js +224 -63
  47. package/lib/esm/components/CaseEditView/Tabs/CaseSummary/CaseSummary.d.ts.map +1 -1
  48. package/lib/esm/components/CaseEditView/Tabs/CaseSummary/CaseSummary.js +2 -7
  49. package/lib/esm/components/CaseEditView/Tabs/RMEEscalations/RMEEscalationList.d.ts.map +1 -1
  50. package/lib/esm/components/CaseEditView/Tabs/RMEEscalations/RMEEscalationList.js +9 -7
  51. package/lib/esm/components/CaseInformation/CaseInformation.d.ts.map +1 -1
  52. package/lib/esm/components/CaseInformation/CaseInformation.js +5 -7
  53. package/lib/esm/components/CaseInformation/ContactPhoneNumber.d.ts.map +1 -1
  54. package/lib/esm/components/CaseInformation/ContactPhoneNumber.js +24 -37
  55. package/lib/esm/components/CaseInformation/SupportLevel.d.ts.map +1 -1
  56. package/lib/esm/components/CaseInformation/SupportLevel.js +55 -32
  57. package/lib/esm/components/CaseManagement/CaseLanguageSelector.js +2 -2
  58. package/lib/esm/components/CaseManagement/CaseManagement.d.ts.map +1 -1
  59. package/lib/esm/components/CaseManagement/CaseManagement.js +9 -4
  60. package/lib/esm/components/CaseManagement/Cep.d.ts.map +1 -1
  61. package/lib/esm/components/CaseManagement/Cep.js +7 -4
  62. package/lib/esm/components/IdeaInformation/IdeaInformation.d.ts.map +1 -1
  63. package/lib/esm/components/IdeaInformation/IdeaInformation.js +12 -11
  64. package/lib/esm/components/OpenCase/SupportTypeSelectorPage.d.ts.map +1 -1
  65. package/lib/esm/components/OpenCase/SupportTypeSelectorPage.js +2 -4
  66. package/lib/esm/components/ProductSelector/AllProductsSelector.d.ts +1 -0
  67. package/lib/esm/components/ProductSelector/AllProductsSelector.d.ts.map +1 -1
  68. package/lib/esm/components/ProductSelector/AllProductsSelector.js +15 -3
  69. package/lib/esm/components/ProductSelector/NewProductDropdownSelector.d.ts.map +1 -1
  70. package/lib/esm/components/ProductSelector/NewProductDropdownSelector.js +37 -13
  71. package/lib/esm/components/ProductSelector/NewProductVersionSelector.d.ts.map +1 -1
  72. package/lib/esm/components/ProductSelector/NewProductVersionSelector.js +50 -30
  73. package/lib/esm/components/ProductSelector/ProductSelector.d.ts.map +1 -1
  74. package/lib/esm/components/ProductSelector/ProductSelector.js +3 -1
  75. package/lib/esm/components/Review/Review.d.ts.map +1 -1
  76. package/lib/esm/components/Review/Review.js +18 -16
  77. package/lib/esm/components/SessionRestore/SessionRestore.d.ts.map +1 -1
  78. package/lib/esm/components/SessionRestore/SessionRestore.js +1 -3
  79. package/lib/esm/components/UpdateSeverityModal/UpdateSeverityModal.d.ts.map +1 -1
  80. package/lib/esm/components/UpdateSeverityModal/UpdateSeverityModal.js +8 -5
  81. package/lib/esm/components/shared/useIsSectionValid.d.ts.map +1 -1
  82. package/lib/esm/components/shared/useIsSectionValid.js +64 -50
  83. package/lib/esm/components/shared/usePostComment.d.ts.map +1 -1
  84. package/lib/esm/components/shared/usePostComment.js +10 -6
  85. package/lib/esm/components/wizardLayout/GlobalTroubleshootEffects.d.ts.map +1 -1
  86. package/lib/esm/components/wizardLayout/GlobalTroubleshootEffects.js +24 -105
  87. package/lib/esm/components/wizardLayout/WizardLayout.d.ts.map +1 -1
  88. package/lib/esm/components/wizardLayout/WizardLayout.js +7 -6
  89. package/lib/esm/components/wizardLayout/WizardNavigation.d.ts.map +1 -1
  90. package/lib/esm/components/wizardLayout/WizardNavigation.js +10 -10
  91. package/lib/esm/context/CaseContext.d.ts.map +1 -1
  92. package/lib/esm/hooks/useResetCaseCreate.d.ts.map +1 -1
  93. package/lib/esm/hooks/useResetCaseCreate.js +11 -18
  94. package/lib/esm/reducers/CaseConstNTypes.d.ts +3 -86
  95. package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
  96. package/lib/esm/reducers/CaseConstNTypes.js +1 -5
  97. package/lib/esm/reducers/CaseDetailsPageReducer.d.ts +1 -3
  98. package/lib/esm/reducers/CaseDetailsPageReducer.d.ts.map +1 -1
  99. package/lib/esm/reducers/CaseDetailsPageReducer.js +5 -22
  100. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts +2 -0
  101. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts.map +1 -1
  102. package/lib/esm/reducers/CaseDiscussionTabReducer.js +28 -1
  103. package/lib/esm/reducers/CaseHelpers.d.ts +1 -2
  104. package/lib/esm/reducers/CaseHelpers.d.ts.map +1 -1
  105. package/lib/esm/reducers/CaseHelpers.js +2 -34
  106. package/lib/esm/reducers/CaseOverviewReducer.d.ts +1 -3
  107. package/lib/esm/reducers/CaseOverviewReducer.d.ts.map +1 -1
  108. package/lib/esm/reducers/CaseOverviewReducer.js +5 -7
  109. package/lib/esm/reducers/CaseReducer.d.ts +8 -27
  110. package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
  111. package/lib/esm/reducers/CaseReducer.js +33 -127
  112. package/package.json +6 -6
  113. package/lib/esm/components/CaseEditView/RequestRemoteSession/remoteSessionUtils.d.ts +0 -3
  114. package/lib/esm/components/CaseEditView/RequestRemoteSession/remoteSessionUtils.d.ts.map +0 -1
  115. package/lib/esm/components/CaseEditView/RequestRemoteSession/remoteSessionUtils.js +0 -22
  116. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.d.ts +0 -15
  117. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.d.ts.map +0 -1
  118. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.js +0 -19
  119. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useCommentDrafts.d.ts +0 -17
  120. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useCommentDrafts.d.ts.map +0 -1
  121. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useCommentDrafts.js +0 -49
  122. package/lib/esm/graphql/index.d.ts +0 -4
  123. package/lib/esm/graphql/index.d.ts.map +0 -1
  124. package/lib/esm/graphql/index.js +0 -3
  125. package/lib/esm/graphql/mutations/createRMECaseEscalation.d.ts +0 -2
  126. package/lib/esm/graphql/mutations/createRMECaseEscalation.d.ts.map +0 -1
  127. package/lib/esm/graphql/mutations/createRMECaseEscalation.js +0 -24
  128. package/lib/esm/graphql/mutations/index.d.ts +0 -2
  129. package/lib/esm/graphql/mutations/index.d.ts.map +0 -1
  130. package/lib/esm/graphql/mutations/index.js +0 -1
  131. package/lib/esm/graphql/queries/getEscalationDetails.d.ts +0 -2
  132. package/lib/esm/graphql/queries/getEscalationDetails.d.ts.map +0 -1
  133. package/lib/esm/graphql/queries/getEscalationDetails.js +0 -24
  134. package/lib/esm/graphql/queries/getParentId.d.ts +0 -2
  135. package/lib/esm/graphql/queries/getParentId.d.ts.map +0 -1
  136. package/lib/esm/graphql/queries/getParentId.js +0 -16
  137. package/lib/esm/graphql/queries/index.d.ts +0 -3
  138. package/lib/esm/graphql/queries/index.d.ts.map +0 -1
  139. package/lib/esm/graphql/queries/index.js +0 -2
  140. package/lib/esm/graphql/schemas/escalation.d.ts +0 -84
  141. package/lib/esm/graphql/schemas/escalation.d.ts.map +0 -1
  142. package/lib/esm/graphql/schemas/escalation.js +0 -1
  143. package/lib/esm/graphql/schemas/index.d.ts +0 -2
  144. package/lib/esm/graphql/schemas/index.d.ts.map +0 -1
  145. package/lib/esm/graphql/schemas/index.js +0 -1
  146. package/lib/esm/hooks/useCaseComments/caseCommentMutation.d.ts +0 -4
  147. package/lib/esm/hooks/useCaseComments/caseCommentMutation.d.ts.map +0 -1
  148. package/lib/esm/hooks/useCaseComments/caseCommentMutation.js +0 -12
  149. package/lib/esm/hooks/useCaseComments/caseCommentsQuery.d.ts +0 -4
  150. package/lib/esm/hooks/useCaseComments/caseCommentsQuery.d.ts.map +0 -1
  151. package/lib/esm/hooks/useCaseComments/caseCommentsQuery.js +0 -55
  152. package/lib/esm/hooks/useCaseComments/index.d.ts +0 -7
  153. package/lib/esm/hooks/useCaseComments/index.d.ts.map +0 -1
  154. package/lib/esm/hooks/useCaseComments/index.js +0 -5
  155. package/lib/esm/hooks/useCaseComments/mapCaseComment.d.ts +0 -25
  156. package/lib/esm/hooks/useCaseComments/mapCaseComment.d.ts.map +0 -1
  157. package/lib/esm/hooks/useCaseComments/mapCaseComment.js +0 -66
  158. package/lib/esm/hooks/useCaseComments/types.d.ts +0 -80
  159. package/lib/esm/hooks/useCaseComments/types.d.ts.map +0 -1
  160. package/lib/esm/hooks/useCaseComments/types.js +0 -1
  161. package/lib/esm/hooks/useCaseComments/useCaseComments.d.ts +0 -16
  162. package/lib/esm/hooks/useCaseComments/useCaseComments.d.ts.map +0 -1
  163. package/lib/esm/hooks/useCaseComments/useCaseComments.js +0 -25
  164. package/lib/esm/hooks/useCaseComments/useCreateCaseComment.d.ts +0 -19
  165. package/lib/esm/hooks/useCaseComments/useCreateCaseComment.d.ts.map +0 -1
  166. package/lib/esm/hooks/useCaseComments/useCreateCaseComment.js +0 -33
  167. package/lib/esm/hooks/useCaseHistory.d.ts +0 -26
  168. package/lib/esm/hooks/useCaseHistory.d.ts.map +0 -1
  169. package/lib/esm/hooks/useCaseHistory.js +0 -98
  170. package/lib/esm/models/caseHistory.d.ts +0 -80
  171. package/lib/esm/models/caseHistory.d.ts.map +0 -1
  172. package/lib/esm/models/caseHistory.js +0 -1
  173. package/lib/esm/utils/TimelineUtils.d.ts +0 -41
  174. package/lib/esm/utils/TimelineUtils.d.ts.map +0 -1
  175. package/lib/esm/utils/TimelineUtils.js +0 -134
  176. package/lib/esm/utils/caseHistoryUtils.d.ts +0 -66
  177. package/lib/esm/utils/caseHistoryUtils.d.ts.map +0 -1
  178. package/lib/esm/utils/caseHistoryUtils.js +0 -165
@@ -7,92 +7,104 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- // TODO: Re-enable after GraphQL migration of attachments
11
- // import { IAttachment } from '@cee-eng/hydrajs/@types/models/attachment';
12
- import { Button, ButtonVariant, Checkbox } from '@patternfly/react-core';
13
- import { EditorMode, LoadingIndicator, MarkdownEditor, ToastNotification, usePrevious } from '@rh-support/components';
14
- import { GlobalMetadataStateContext, useCanEditCase, useUserPreferences } from '@rh-support/react-context';
15
- import { ability, CaseDiscussionFields, resourceActions, resources } from '@rh-support/user-permissions';
10
+ import { publicApi } from '@cee-eng/hydrajs';
11
+ import { Button, ButtonVariant, Checkbox, debounce, Tooltip } from '@patternfly/react-core';
12
+ import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon';
13
+ import { EditorMode, LoadingIndicator, MarkdownEditor, ToastNotification, useFetch, usePrevious, } from '@rh-support/components';
14
+ import { FeatureAnnouncementKeys, GlobalMetadataStateContext, NewFeaturePopoverAnnouncement, useCanEditCase, useUserPreferences, } from '@rh-support/react-context';
15
+ import { ability, CaseDiscussionFields, CaseListFields, resourceActions, resources, } from '@rh-support/user-permissions';
16
+ import { pendoTrackEvent } from '@rh-support/utils';
16
17
  import isEmpty from 'lodash/isEmpty';
17
18
  import isEqual from 'lodash/isEqual';
18
- import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
19
+ import uniqBy from 'lodash/uniqBy';
20
+ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
21
+ import { useDropzone } from 'react-dropzone';
19
22
  import { Trans, useTranslation } from 'react-i18next';
20
23
  import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
21
- import { useCreateCaseComment } from '../../../../hooks/useCaseComments';
24
+ import { CaseDetailsCacheNamespaces } from '../../../../enums/cache';
22
25
  import { useCaseUpdateErrorMessage } from '../../../../hooks/useCaseUpdateErrorMessage';
23
- import { checkForCaseStatusToggleOnAttachOrComment } from '../../../../reducers/CaseReducer';
24
- // TODO: Re-enable after GraphQL migration of attachments
25
- // import { markdownFilePasteEvent } from '../../../shared/Constants';
26
- // import {
27
- // AttachmentDispatchContext,
28
- // AttachmentStateContext,
29
- // hasSomeSelectedFiles,
30
- // hasSomeUnUploadedAttachments,
31
- // isUploadingAttachment,
32
- // resetAttachment,
33
- // } from '../../../shared/fileUpload';
34
- // import FileSelectorButton from '../../../shared/fileUpload/fileSelectors/FileSelectorButton';
35
- // import FileUpload from '../../../shared/fileUpload/FileUpload';
26
+ import { DiscussionType } from '../../../../reducers/CaseDiscussionTabReducer';
27
+ import { addingNotifiedUsers, checkForCaseStatusToggleOnAttachOrComment, setNotifiedUser, } from '../../../../reducers/CaseReducer';
28
+ import { CaseDetailsCacheUtils } from '../../../../utils/caseDetailsCacheUtils';
29
+ import { markdownFilePasteEvent } from '../../../shared/Constants';
30
+ import { AttachmentDispatchContext, AttachmentStateContext, hasSomeSelectedFiles, hasSomeUnUploadedAttachments, isUploadingAttachment, resetAttachment, } from '../../../shared/fileUpload';
31
+ import FileSelectorButton from '../../../shared/fileUpload/fileSelectors/FileSelectorButton';
32
+ import FileUpload from '../../../shared/fileUpload/FileUpload';
36
33
  import { PDFContext } from '../../PDFContainer';
37
- // TODO: Re-enable after GraphQL migration of attachments
38
- // import { useAttachmentUploadCompletion } from './PostComment/useAttachmentUploadCompletion';
39
- import { useCommentDrafts } from './PostComment/useCommentDrafts';
40
- // import { useMarkdownFileUploader } from './PostComment/useMarkdownFileUploader';
34
+ import { useMarkdownFileUploader } from './PostComment/useMarkdownFileUploader';
41
35
  import { VerifyCaseStatusModal } from './VerifyCaseStatusModal/VerifyCaseStatusModal';
42
36
  export function PostComment(props) {
43
- var _a;
37
+ var _a, _b;
44
38
  const { t } = useTranslation();
45
39
  const caseUpdateError = useCaseUpdateErrorMessage();
46
40
  let { caseNumber } = props;
47
41
  const [isTextAreaFocused, setIsTextAreaFocused] = useState(false);
42
+ const canAddAttachments = ability.can(resourceActions.PATCH, resources.CASE_CREATE, CaseListFields.ATTACHMENTS);
48
43
  const canPostPrivateComments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.POST_PRIVATE_COMMENT);
49
- const { createComment, loading: isPostingComment } = useCreateCaseComment();
44
+ const { request, isFetching: isPostingComment } = useFetch(publicApi.kase.postComment, {
45
+ propgateErrors: true,
46
+ });
47
+ const dispatchToAttachmentReducer = useContext(AttachmentDispatchContext);
48
+ const { attachmentState } = useContext(AttachmentStateContext);
49
+ const [commentText, setCommentText] = useState(props.commentText || '');
50
50
  const [isPublic, setIsPublic] = useState(props.defaultIsPublic === null ? true : props.defaultIsPublic);
51
+ const isPublicRef = useRef(isPublic);
52
+ const isUploadingAttachmentPrevious = useRef(false);
53
+ const isUploadingAttachments = isUploadingAttachment(attachmentState.caseFiles.selectedLocalFiles);
54
+ const hasSomeUnUploadedFiles = hasSomeUnUploadedAttachments(attachmentState.caseFiles.selectedLocalFiles);
55
+ const hasSomeSelectedFilesLocal = hasSomeSelectedFiles(attachmentState.caseFiles.selectedLocalFiles);
51
56
  const [commentType, setCommentType] = useState(EditorMode.PLAIN);
52
57
  const [commentSignature, setCommentSignature] = useState('');
53
- const [commentText, setCommentText] = useState(props.commentText || '');
54
58
  const { isExportingPDF } = useContext(PDFContext);
55
59
  const { getCommentTypeFromPreference, getCommentSignature } = useUserPreferences();
56
- const applySignature = useCallback((text) => {
57
- if (isEmpty(commentSignature))
58
- return;
59
- const signed = text.includes(commentSignature) ? text : text + '\n' + commentSignature;
60
- setCommentText(signed);
61
- }, [commentSignature]);
62
- useEffect(() => {
63
- function loadPrefs() {
64
- return __awaiter(this, void 0, void 0, function* () {
65
- try {
66
- yield getCommentTypeFromPreference();
67
- const sig = (yield getCommentSignature()) || '';
68
- setCommentType(EditorMode.PLAIN);
69
- setCommentSignature(sig);
70
- if (isEmpty(commentText) && !isEmpty(sig)) {
71
- setCommentText(`\n ${sig}`);
72
- }
73
- }
74
- catch (error) {
75
- console.error('Failed to load comment preferences:', error);
76
- }
77
- });
60
+ const userOriginalCommentPrefs = () => __awaiter(this, void 0, void 0, function* () {
61
+ try {
62
+ const retrievedComment = yield getCommentTypeFromPreference();
63
+ const retrievedCommentSignature = yield getCommentSignature();
64
+ const defaultCommentType = retrievedComment ? retrievedComment : EditorMode.PLAIN;
65
+ // @ts-ignore
66
+ setCommentType(defaultCommentType);
67
+ const defaultCommentSignature = retrievedCommentSignature || '';
68
+ setCommentSignature(defaultCommentSignature);
69
+ if (isEmpty(commentText) && !isEmpty(defaultCommentSignature)) {
70
+ setCommentText(`\n ${defaultCommentSignature}` || '');
71
+ }
72
+ }
73
+ catch (error) {
74
+ console.log(error);
78
75
  }
79
- loadPrefs();
76
+ });
77
+ useEffect(() => {
78
+ userOriginalCommentPrefs();
80
79
  // eslint-disable-next-line react-hooks/exhaustive-deps
81
80
  }, []);
82
81
  const [isModalOpen, setIsModalOpen] = useState(false);
83
82
  const [cssCommentAgreed, setCssCommentAgreed] = useState(false);
84
- const [isProcessing, setIsProcessing] = useState(false);
83
+ const [isProcessing, setIsProcessing] = useState(isPostingComment || isUploadingAttachments);
85
84
  const { globalMetadataState: { loggedInUser, loggedInUserRights, loggedInUsersAccount }, } = useContext(GlobalMetadataStateContext);
86
- const { status, caseSalesforceId } = useCaseSelector((state) => ({
85
+ const { onFileSelect, onFileAttach, onFileDelete, isUploadingFile, isMarkdownFileUploadInProgress, cancelFileUpload, } = useMarkdownFileUploader({
86
+ caseNumber,
87
+ secureSupport: loggedInUsersAccount.data.secureSupport,
88
+ onAttachmentAdded: props.onAttachmentAdded,
89
+ });
90
+ const { selectedNotificationContacts, status, contactSSOName, selectedAccountDetails } = useCaseSelector((state) => ({
87
91
  status: state.caseDetails.status,
88
- caseSalesforceId: state.caseDetails.id,
92
+ contactSSOName: state.caseDetails.contactSSOName,
93
+ selectedNotificationContacts: state.selectedNotificationContacts,
94
+ selectedAccountDetails: state.selectedAccountDetails,
89
95
  }), isEqual);
90
- const isConfirmedStateSideSupport = (_a = loggedInUsersAccount === null || loggedInUsersAccount === void 0 ? void 0 : loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.hasConfirmedStatesideSupport;
96
+ const isConfirmedStateSideSupport = ((_a = loggedInUsersAccount === null || loggedInUsersAccount === void 0 ? void 0 : loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.hasConfirmedStatesideSupport) ||
97
+ ((_b = selectedAccountDetails === null || selectedAccountDetails === void 0 ? void 0 : selectedAccountDetails.data) === null || _b === void 0 ? void 0 : _b.hasConfirmedStatesideSupport);
91
98
  const caseDispatch = useCaseDispatch();
92
99
  const [isCommentTooLong, setIsCommentTooLong] = useState(false);
93
100
  const canEditCase = useCanEditCase();
94
101
  const componentRef = useRef(null);
95
102
  let passedReply = props.commentText;
103
+ const { getRootProps, getInputProps, open } = useDropzone({
104
+ onDrop: (files) => onFileAttach(files, isPublic),
105
+ multiple: false,
106
+ });
107
+ // Allows the isPublic default state to be changed by the parent component
96
108
  const resetIsPublic = useCallback(() => setIsPublic(props.defaultIsPublic === null ? true : props.defaultIsPublic), [props.defaultIsPublic]);
97
109
  const previousDefaultIsPublic = usePrevious(props.defaultIsPublic);
98
110
  useEffect(() => {
@@ -100,107 +112,99 @@ export function PostComment(props) {
100
112
  return;
101
113
  props.defaultIsPublic === null ? resetIsPublic() : setIsPublic(props.defaultIsPublic);
102
114
  }, [props.defaultIsPublic, resetIsPublic, previousDefaultIsPublic]);
115
+ // why usecallback instead of useRef?
116
+ // https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node
103
117
  const textAreaRef = useCallback((node) => {
104
- const isReplyMatch = node !== null &&
118
+ if (node !== null &&
105
119
  props.commentText &&
106
120
  props.commentCreator &&
107
121
  commentText &&
108
- commentText === getReplyText(props.commentText, props.commentCreator);
109
- if (!isReplyMatch)
110
- return;
111
- node.scrollTop = node.scrollHeight;
112
- node.focus();
122
+ commentText === getReplyText(props.commentText, props.commentCreator)) {
123
+ node.scrollTop = node.scrollHeight;
124
+ node.focus();
125
+ }
113
126
  },
114
127
  // eslint-disable-next-line react-hooks/exhaustive-deps
115
128
  [commentText]);
116
- const loggedInUserSSO = loggedInUserRights.data.getSSOUsername();
117
- const { saveDraft, clearDraft } = useCommentDrafts({
118
- caseNumber,
119
- loggedInUserSSO,
120
- commentSignature,
121
- setCommentText,
122
- setCommentType,
123
- setIsPublic,
124
- applySignature,
125
- });
126
129
  const resetCommentSection = () => __awaiter(this, void 0, void 0, function* () {
127
- var _a;
128
130
  setCommentText('');
129
131
  setIsTextAreaFocused(false);
130
132
  resetIsPublic();
131
- yield clearDraft();
132
- (_a = props.onCommentClear) === null || _a === void 0 ? void 0 : _a.call(props);
133
- setCommentText(commentSignature ? `\n ${commentSignature}` : '');
133
+ const { value: prevDraftComments = {} } = (yield CaseDetailsCacheUtils.get(CaseDetailsCacheNamespaces.COMMENTS_DRAFT.name, loggedInUserRights.data.getSSOUsername())) || {};
134
+ if (prevDraftComments[caseNumber]) {
135
+ delete prevDraftComments[caseNumber];
136
+ }
137
+ CaseDetailsCacheUtils.set(CaseDetailsCacheNamespaces.COMMENTS_DRAFT.name, loggedInUserRights.data.getSSOUsername(), { value: prevDraftComments });
138
+ props.onCommentClear && props.onCommentClear();
139
+ setCommentText(`\n ${commentSignature}` || '');
134
140
  });
141
+ const resetAttachmentSection = () => {
142
+ resetAttachment(dispatchToAttachmentReducer);
143
+ };
135
144
  const onCancelClick = () => {
136
145
  resetCommentSection();
146
+ resetAttachmentSection();
147
+ cancelFileUpload();
137
148
  };
149
+ const loggedInUserSSO = loggedInUserRights.data.getSSOUsername();
150
+ // https://github.com/facebook/react/issues/19240
151
+ const debouncedCacheSave = useMemo(() => debounce(function (value, mode, publicFlag) {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ const { value: prevDraftComments = {} } = (yield CaseDetailsCacheUtils.get(CaseDetailsCacheNamespaces.COMMENTS_DRAFT.name, loggedInUserSSO)) || {};
154
+ if (prevDraftComments[caseNumber]) {
155
+ }
156
+ prevDraftComments[caseNumber] = { text: value, privateFlag: !publicFlag, type: mode };
157
+ CaseDetailsCacheUtils.set(CaseDetailsCacheNamespaces.COMMENTS_DRAFT.name, loggedInUserSSO, {
158
+ value: prevDraftComments,
159
+ });
160
+ });
161
+ }, 500), [caseNumber, loggedInUserSSO]);
138
162
  const onCommentTextChange = (value, mode) => __awaiter(this, void 0, void 0, function* () {
139
- setCommentType(mode !== null && mode !== void 0 ? mode : commentType);
140
- setCommentText(value !== null && value !== void 0 ? value : '');
141
- saveDraft(value, mode, isPublic);
163
+ setCommentType(mode);
164
+ setCommentText(value);
165
+ debouncedCacheSave(value, mode, isPublic);
142
166
  });
143
- const onCancel = () => {
144
- setIsModalOpen(false);
145
- };
146
- const isNotInternalConfirm = () => {
147
- onPostComment();
148
- };
149
- const onConfirm = () => {
150
- setIsModalOpen(false);
151
- isNotInternalConfirm();
152
- };
153
- const onBtnClick = () => {
154
- setIsModalOpen(true);
155
- };
156
- // TODO: Re-enable after GraphQL migration (REST notification)
157
- // const addUserToNotifyList = async () => {
158
- // const sso = loggedInUserRights.data.getSSOUsername();
159
- // const alreadyNotified = (selectedNotificationContacts || []).some((item) => item.ssoUsername === sso);
160
- // if (sso === contactSSOName || alreadyNotified) return;
161
- // await addingNotifiedUsers(caseDispatch, caseNumber, [{ ssoUsername: sso }]);
162
- // setNotifiedUser(caseDispatch, uniqBy([...selectedNotificationContacts, loggedInUser.data], 'ssoUsername'));
163
- // };
164
- const checkCommentSignature = commentText.replace(commentSignature, '');
165
- const isCommentEmpty = isEmpty(checkCommentSignature === null || checkCommentSignature === void 0 ? void 0 : checkCommentSignature.trim());
167
+ const addUserToNotifyList = () => __awaiter(this, void 0, void 0, function* () {
168
+ const loggedInUserSSO = loggedInUserRights.data.getSSOUsername();
169
+ if (loggedInUserSSO !== contactSSOName &&
170
+ !(selectedNotificationContacts || []).map((item) => item.ssoUsername).includes(loggedInUserSSO)) {
171
+ yield addingNotifiedUsers(caseDispatch, caseNumber, [{ ssoUsername: loggedInUserSSO }]);
172
+ setNotifiedUser(caseDispatch, uniqBy([...selectedNotificationContacts, loggedInUser.data], 'ssoUsername'));
173
+ }
174
+ });
175
+ useEffect(() => {
176
+ isPublicRef.current = isPublic;
177
+ }, [isPublic]);
166
178
  useEffect(() => {
167
- var _a;
168
179
  if (isCommentEmpty) {
169
- (_a = props.onCommentClear) === null || _a === void 0 ? void 0 : _a.call(props);
180
+ props.onCommentClear && props.onCommentClear();
170
181
  }
171
182
  // eslint-disable-next-line react-hooks/exhaustive-deps
172
183
  }, [commentText]);
184
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
173
185
  const onPostComment = () => __awaiter(this, void 0, void 0, function* () {
174
- var _a;
175
186
  if (canEditCase.alert())
176
187
  return;
177
- if (!commentText)
178
- return;
179
- if (!caseSalesforceId)
180
- return;
181
- try {
182
- setIsProcessing(true);
183
- yield createComment({
184
- caseId: caseSalesforceId,
185
- body: commentText,
186
- isPublic,
187
- isAssociate: loggedInUserRights.data.isInternal(),
188
- });
189
- checkForCaseStatusToggleOnAttachOrComment(caseDispatch, loggedInUserRights.data.isInternal(), status);
190
- if (!isPublic)
191
- setIsPublic(true);
192
- // TODO: Re-enable after GraphQL migration (REST notification)
193
- // addUserToNotifyList();
194
- yield ((_a = props.onCommentAdded) === null || _a === void 0 ? void 0 : _a.call(props));
195
- resetCommentSection();
196
- ToastNotification.addSuccessMessage(t('Comment submitted'));
197
- setCssCommentAgreed(false);
198
- }
199
- catch (e) {
200
- caseUpdateError.showError(e, t('Could not submit comment'));
201
- }
202
- finally {
203
- setIsProcessing(false);
188
+ if (commentText) {
189
+ try {
190
+ setIsProcessing(true);
191
+ const newCommentText = commentText.replace(/(^|\n)(-\s.+)(\n(?![-\s]))/g, '$1$2\n\n');
192
+ yield request({ caseNumber, commentBody: newCommentText, isPublic, contentType: commentType });
193
+ checkForCaseStatusToggleOnAttachOrComment(caseDispatch, loggedInUserRights.data.isInternal(), status);
194
+ !isPublic && setIsPublic(true);
195
+ addUserToNotifyList();
196
+ // update state
197
+ yield props.onCommentAdded();
198
+ resetCommentSection();
199
+ ToastNotification.addSuccessMessage(t('Comment submitted'));
200
+ setCssCommentAgreed(false);
201
+ }
202
+ catch (e) {
203
+ caseUpdateError.showError(e, t('Could not submit comment'));
204
+ }
205
+ finally {
206
+ setIsProcessing(false);
207
+ }
204
208
  }
205
209
  });
206
210
  const handleCheckboxToggle = () => {
@@ -210,11 +214,10 @@ export function PostComment(props) {
210
214
  return commentText.trim() === commentSignature;
211
215
  }
212
216
  const isPostCommentDisabled = isProcessing || !commentText || isCommentSignatureMatch();
213
- /**
214
- * Formats a reply as a markdown blockquote. Truncates the original text
215
- * to 1000 characters, prepends an attribution header, and prefixes each
216
- * line with `> ` for blockquote rendering.
217
- */
217
+ const isFileUploadDisabled = isConfirmedStateSideSupport && !cssCommentAgreed;
218
+ const onFileUploadClick = () => {
219
+ ToastNotification.addInfoMessage(t('Uploading Attachment(s)'));
220
+ };
218
221
  const getReplyText = (replyText, commentCreator) => {
219
222
  const person = t(`(replying to {{commentCreator}}) \n`, { commentCreator });
220
223
  const reply = replyText
@@ -223,29 +226,103 @@ export function PostComment(props) {
223
226
  .reduce((acc, line) => (acc += '> ' + line + '\n'), person);
224
227
  return reply;
225
228
  };
229
+ const addCommentSignature = (preSigComment) => {
230
+ if (!isEmpty(commentSignature)) {
231
+ let signedComment = '';
232
+ // Checks if somment signature already exists and depending on that check, adds the signature
233
+ if (preSigComment.includes(commentSignature)) {
234
+ signedComment = preSigComment;
235
+ }
236
+ else {
237
+ signedComment = preSigComment + '\n' + commentSignature;
238
+ }
239
+ setCommentText(signedComment);
240
+ }
241
+ };
226
242
  useEffect(() => {
227
- if (!props.commentText || !props.commentCreator)
243
+ if (!props.commentText || !props.commentCreator) {
228
244
  return;
245
+ }
229
246
  const reply = getReplyText(props.commentText, props.commentCreator);
230
247
  if (reply.includes(commentSignature)) {
231
248
  setCommentText(reply);
232
249
  }
233
250
  else {
234
- applySignature(reply);
251
+ addCommentSignature(reply);
235
252
  }
236
253
  // eslint-disable-next-line react-hooks/exhaustive-deps
237
254
  }, [props.commentText, props.commentCreator]);
255
+ useEffect(() => {
256
+ if (isUploadingAttachmentPrevious.current && !isUploadingAttachments && !hasSomeUnUploadedFiles) {
257
+ ToastNotification.addSuccessMessage(t('Attachment(s) uploaded successfully'));
258
+ checkForCaseStatusToggleOnAttachOrComment(caseDispatch, loggedInUserRights.data.isInternal(), status);
259
+ // update state
260
+ resetAttachmentSection();
261
+ props.onAttachmentAdded();
262
+ setCssCommentAgreed(false);
263
+ }
264
+ isUploadingAttachmentPrevious.current = isUploadingAttachments;
265
+ // eslint-disable-next-line react-hooks/exhaustive-deps
266
+ }, [isUploadingAttachments]);
267
+ useEffect(() => {
268
+ function getDraftComments() {
269
+ return __awaiter(this, void 0, void 0, function* () {
270
+ const { value: draftComments = {} } = (yield CaseDetailsCacheUtils.get(CaseDetailsCacheNamespaces.COMMENTS_DRAFT.name, loggedInUserRights.data.getSSOUsername())) || {};
271
+ if (draftComments[caseNumber]) {
272
+ const { text, privateFlag, type } = draftComments[caseNumber];
273
+ if (text.trim()) {
274
+ addCommentSignature(text);
275
+ privateFlag === true && setIsPublic(false);
276
+ setCommentType(type);
277
+ }
278
+ }
279
+ });
280
+ }
281
+ getDraftComments();
282
+ // eslint-disable-next-line react-hooks/exhaustive-deps
283
+ }, [commentSignature]);
238
284
  const onTextAreaBlur = () => {
239
- if (!commentText)
240
- setIsTextAreaFocused(false);
285
+ !commentText && setIsTextAreaFocused(false);
241
286
  };
242
287
  const onCommentExceedCharsLimit = (lengthExceededNew) => {
243
288
  if (isCommentTooLong !== lengthExceededNew)
244
289
  setIsCommentTooLong(lengthExceededNew);
245
290
  };
291
+ const showCaseIsNotEditableAlert = () => {
292
+ if (canEditCase.alert())
293
+ return;
294
+ };
295
+ const fileUploadButton = (React.createElement(React.Fragment, null, canEditCase.isCaseNotEditable ? (React.createElement(Button, { variant: ButtonVariant.secondary, onClick: showCaseIsNotEditableAlert, isDisabled: isFileUploadDisabled }, t(isPublic || !canPostPrivateComments ? 'Attach files' : 'Attach private files'))) : (React.createElement(FileSelectorButton, { buttonLabel: t(isPublic || !canPostPrivateComments ? 'Attach files' : 'Attach private files'), isSessionId: false, isPrivate: !isPublic, "data-tracking-id": "case-discussion-file-selector-button", isDisabled: isFileUploadDisabled }))));
296
+ const markdownToolbarFileSelectorBtn = (React.createElement(Button, { type: "button", onClick: open, "data-tracking-id": "inline-image-attach-file", isDisabled: isUploadingFile, variant: ButtonVariant.link, icon: React.createElement(PlusIcon, null) }, t(isPublic ? 'Attach files' : 'Attach private files')));
297
+ // This is where we get all attachments to show in dropdown
298
+ const getAllAttachments = () => {
299
+ return (props.allDiscussions || [])
300
+ .filter((item) => item.discussionType === DiscussionType.ATTACHMENT)
301
+ .map((elem) => elem.item);
302
+ };
303
+ const onClipboardPaste = (files) => {
304
+ pendoTrackEvent(markdownFilePasteEvent);
305
+ onFileAttach(files, isPublicRef.current);
306
+ };
307
+ const onCancel = () => {
308
+ setIsModalOpen(false);
309
+ };
310
+ const isNotInternalConfirm = () => {
311
+ onPostComment();
312
+ };
313
+ const onConfirm = (commentText) => {
314
+ setIsModalOpen(false);
315
+ isNotInternalConfirm();
316
+ };
317
+ const onBtnClick = () => {
318
+ setIsModalOpen(true);
319
+ };
320
+ // To check is commment is empty
321
+ const checkCommentSignature = commentText.replace(commentSignature, '');
322
+ const isCommentEmpty = isEmpty(checkCommentSignature === null || checkCommentSignature === void 0 ? void 0 : checkCommentSignature.trim());
323
+ // To check is comment reply is empty and disable if it is
246
324
  const isReplyDisabled = () => {
247
- var _a;
248
- let parsedPassedReply = getReplyText(passedReply !== null && passedReply !== void 0 ? passedReply : '', (_a = props.commentCreator) !== null && _a !== void 0 ? _a : '');
325
+ let parsedPassedReply = getReplyText(passedReply, props.commentCreator);
249
326
  return (parsedPassedReply === null || parsedPassedReply === void 0 ? void 0 : parsedPassedReply.trim()) === (commentText === null || commentText === void 0 ? void 0 : commentText.trim());
250
327
  };
251
328
  const isSubmitDisabled = isReplyDisabled() ||
@@ -253,10 +330,20 @@ export function PostComment(props) {
253
330
  isPostCommentDisabled ||
254
331
  (isConfirmedStateSideSupport && !cssCommentAgreed);
255
332
  return (React.createElement("div", { className: `pf-v6-u-mb-md ${isExportingPDF ? 'hide-in-pdf' : ''}`, ref: componentRef },
256
- React.createElement(MarkdownEditor, { className: `${!isPublic && canPostPrivateComments ? 'is-private' : ''}`, disabled: isProcessing || canEditCase.isCaseNotEditable, "aria-label": "comment text area", editorMode: commentType, hideToolbars: true, onFocus: () => setIsTextAreaFocused(true), onBlur: onTextAreaBlur, onChange: onCommentTextChange, value: commentText, rows: isTextAreaFocused ? 12 : 4, bindTextArea: textAreaRef, onCommentExceedCharsLimit: onCommentExceedCharsLimit,
257
- // TODO: After GraphQL migration of attachments, restore private-comment placeholder to
258
- // "Add a comment or attach a file privately" when !isPublic && canPostPrivateComments
259
- mdPlaceholder: "Add a comment to this case", plainTextPlaceholder: "Add a comment to this case" }),
333
+ React.createElement(MarkdownEditor, { className: `${!isPublic && canPostPrivateComments ? 'is-private' : ''}`, disabled: isProcessing || canEditCase.isCaseNotEditable, "aria-label": "comment text area", showMarkdownPlainTextToggle: true, editorMode: commentType, onFocus: () => setIsTextAreaFocused(true), onBlur: onTextAreaBlur, onChange: onCommentTextChange, value: commentText, rows: isTextAreaFocused ? 12 : 4, bindTextArea: textAreaRef, onCommentExceedCharsLimit: onCommentExceedCharsLimit, mdPlaceholder: isPublic || !canPostPrivateComments
334
+ ? 'Add a comment using markdown'
335
+ : 'Add a comment or attach a file privately', plainTextPlaceholder: isPublic || !canPostPrivateComments
336
+ ? 'Add a comment to this case'
337
+ : 'Add a comment or attach a file privately', fileSelectorProps: {
338
+ showFileSelectorInToolbar: !loggedInUsersAccount.data.secureSupport,
339
+ filesList: getAllAttachments(),
340
+ onFileSelect: onFileSelect,
341
+ onFileDelete: onFileDelete,
342
+ isSupportedFile: (extension) => true,
343
+ attachFileBtn: markdownToolbarFileSelectorBtn,
344
+ isUploadingFile: isMarkdownFileUploadInProgress,
345
+ onClipboardPaste,
346
+ } }),
260
347
  isConfirmedStateSideSupport && (React.createElement("div", { className: "pf-v6-u-mt-md pf-v6-u-mb-lg" },
261
348
  React.createElement("input", { type: "checkbox", id: "css-case-comment-agreement", name: "css-case-comment-agreement", "data-tracking-id": "css-case-comment-agreement", checked: cssCommentAgreed, onChange: (e) => setCssCommentAgreed(e.target.checked) }),
262
349
  React.createElement("label", { htmlFor: "css-case-comment-agreement", className: "pf-v6-u-font-weight-normal pf-v6-u-font-size-sm" },
@@ -266,8 +353,15 @@ export function PostComment(props) {
266
353
  isModalOpen && loggedInUserRights.data.isInternal() && isPublic && (React.createElement(VerifyCaseStatusModal, { onClose: onCancel, onConfirm: onConfirm, isUpdating: isPostingComment, caseNumber: props.caseNumber })),
267
354
  React.createElement(Button, { "data-tracking-id": "postcomment-submit-button", type: "button", variant: ButtonVariant.primary, onClick: loggedInUser.data.isInternal && isPublic ? onBtnClick : isNotInternalConfirm, isDisabled: isSubmitDisabled, className: "postcomment-submit" },
268
355
  React.createElement(Trans, null, "Submit")),
356
+ canAddAttachments &&
357
+ (isPublic && canPostPrivateComments ? (React.createElement(Tooltip, { content: t('You can attach files privately') }, fileUploadButton)) : (fileUploadButton)),
269
358
  React.createElement(Button, { className: "secondary-button-pill", "data-tracking-id": "postcomment-cancel-button", type: "button", variant: ButtonVariant.link, onClick: onCancelClick, isDisabled: isPostCommentDisabled },
270
359
  React.createElement(Trans, null, "Cancel")),
271
360
  canPostPrivateComments && (React.createElement("span", { className: "post-comment-checkbox" },
272
- React.createElement(Checkbox, { label: t('Private'), isChecked: !isPublic && canPostPrivateComments, onChange: handleCheckboxToggle, "aria-label": t('Private'), id: "private-comment", name: "private-comment", "data-tracking-id": "private-comment-checkbox" })))))));
361
+ React.createElement(Checkbox, { label: t('Private'), isChecked: !isPublic && canPostPrivateComments, onChange: handleCheckboxToggle, "aria-label": t('Private'), id: "private-comment", name: "private-comment", "data-tracking-id": "private-comment-checkbox" }))))),
362
+ React.createElement(FileUpload, { className: `file-upload-section ${hasSomeSelectedFilesLocal ? 'card card-white pf-v6-u-mt-lg pf-v6-u-p-lg' : ''}`, idToUploadTo: caseNumber, onUploadClick: onFileUploadClick, isSessionId: false, isSecureSupport: loggedInUsersAccount.data.secureSupport, isPrivate: !isPublic, autoUploadOnSelect: true, showDescriptionInfoMsg: true }),
363
+ React.createElement("span", Object.assign({}, getRootProps(), { tabIndex: -1 }),
364
+ React.createElement("input", Object.assign({ style: { display: 'none !important' } }, getInputProps()))),
365
+ !loggedInUsersAccount.data.secureSupport && (React.createElement(NewFeaturePopoverAnnouncement, { "aria-label": "Attach and embed images! You'll find all of your uploaded images here.", featureName: FeatureAnnouncementKeys.MARKDOWN_INLINE_IMAGES, sectionRef: componentRef, bodyContent: React.createElement("div", null,
366
+ React.createElement(Trans, null, "Attach and embed images! You'll find all of your uploaded images here.")), triggerRef: () => document.getElementById('md-editor-toolbar-file-selector') }))));
273
367
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VerifyCaseStatusModal.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAsD,MAAM,OAAO,CAAC;AAa3E,UAAU,MAAM;IACZ,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,qBA8IlD"}
1
+ {"version":3,"file":"VerifyCaseStatusModal.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAsD,MAAM,OAAO,CAAC;AAa3E,UAAU,MAAM;IACZ,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,qBA6IlD"}
@@ -7,7 +7,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { useApolloClient } from '@apollo/client/react';
11
10
  import { Button, ButtonVariant, Modal, ModalBody, ModalFooter, ModalHeader, ModalVariant, } from '@patternfly/react-core';
12
11
  import { SingleSelectDropdown, ToastNotification } from '@rh-support/components';
13
12
  import { GlobalMetadataStateContext, useCanEditCase } from '@rh-support/react-context';
@@ -44,12 +43,11 @@ export function VerifyCaseStatusModal(props) {
44
43
  selectedAccountDetails: state.selectedAccountDetails,
45
44
  }), isEqual);
46
45
  const { status } = caseState.caseDetails;
47
- const { globalMetadataState: { loggedInUserRights }, } = useContext(GlobalMetadataStateContext);
48
- const apolloClient = useApolloClient();
46
+ const { globalMetadataState: { loggedInUsersAccount, loggedInUserRights }, } = useContext(GlobalMetadataStateContext);
49
47
  const canManageCase = loggedInUserRights.data.canManageCases();
50
48
  useEffect(() => {
51
- fetchAllStatuses(caseOverviewDispatch, apolloClient);
52
- }, [caseOverviewDispatch, apolloClient]);
49
+ fetchAllStatuses(caseOverviewDispatch, loggedInUsersAccount.data.secureSupport);
50
+ }, [caseOverviewDispatch, loggedInUsersAccount.data.secureSupport]);
53
51
  const { isCaseUpdating } = caseState;
54
52
  const canEditCase = useCanEditCase();
55
53
  const caseDispatch = useCaseDispatch();
@@ -1 +1 @@
1
- {"version":3,"file":"CaseHistory.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/CaseHistory.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,MAAM,sBAQjC,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"CaseHistory.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/CaseHistory.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,MAAM,sBAMjC,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -1,9 +1,7 @@
1
1
  import React from 'react';
2
- import { useCaseSelector } from '../../../../context/CaseContext';
3
2
  import Timeline from './Timeline';
4
3
  const CaseHistory = (props) => {
5
- const sfdcCaseId = useCaseSelector((state) => { var _a; return (_a = state.caseDetails) === null || _a === void 0 ? void 0 : _a.id; });
6
4
  return (React.createElement("div", { className: "pf-v6-u-p-sm" },
7
- React.createElement(Timeline, { caseNumber: props.caseNumber, sfdcCaseId: sfdcCaseId !== null && sfdcCaseId !== void 0 ? sfdcCaseId : '' })));
5
+ React.createElement(Timeline, { caseNumber: props.caseNumber })));
8
6
  };
9
7
  export default CaseHistory;
@@ -121,8 +121,8 @@
121
121
 
122
122
  .timeline-avatar {
123
123
  position: absolute;
124
- left: calc(20% + 2.5px);
125
- transform: translateX(-50%);
124
+ left: calc(20% + 15px);
125
+ transform: translateX(-91%);
126
126
  top: 12px;
127
127
  z-index: 5;
128
128
  }
@@ -134,8 +134,8 @@
134
134
  width: 10px;
135
135
  height: 10px;
136
136
  z-index: 2;
137
- left: calc(20% + 2.5px);
138
- transform: translateX(-50%);
137
+ left: calc(20% + 18px);
138
+ transform: translateX(-195%);
139
139
  top: 25px;
140
140
  }
141
141
 
@@ -1,39 +1,7 @@
1
1
  import './Timeline.css';
2
2
  import React from 'react';
3
- import type { ICaseHistoryItem } from '../../../../models/caseHistory';
4
- import { type IHistoryChangeItem } from '../../../../utils/TimelineUtils';
5
- export interface ITimelineEvent {
6
- date: string;
7
- text: string;
8
- user?: string;
9
- useAvatar?: boolean;
10
- }
11
- export interface ITimelineNodeData {
12
- left: ITimelineEvent;
13
- right: ITimelineEvent;
14
- photoUrl?: string | null;
15
- userName?: string;
16
- }
17
- /**
18
- * Builds the display text for a "Change" history item by resolving values and
19
- * delegating to field-specific formatters.
20
- */
21
- export declare const applyReplacements: (item: IHistoryChangeItem | null | undefined) => string;
22
- /**
23
- * Converts normalized history items into timeline node data for rendering.
24
- *
25
- * Applies a secondary filter (excludes `FolderId__c` and `OwnerId` whose resolved
26
- * display names are unavailable), then maps each item to a left (date/time) and
27
- * right (user action text) event pair. Avatar/date-header boundaries are computed
28
- * sequentially: a new boundary is set on the first item, user change, or date change.
29
- */
30
- export declare const transformApiResponseToTimelineData: (apiResponse: {
31
- historyItems: ICaseHistoryItem[];
32
- }) => ITimelineNodeData[];
33
- interface ITimelineProps {
34
- caseNumber: string;
35
- sfdcCaseId: string | undefined;
36
- }
37
- declare const Timeline: ({ caseNumber, sfdcCaseId }: ITimelineProps) => React.JSX.Element;
3
+ declare const Timeline: ({ caseNumber }: {
4
+ caseNumber: any;
5
+ }) => React.JSX.Element;
38
6
  export default Timeline;
39
7
  //# sourceMappingURL=Timeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAsBxB,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,EAAE,KAAK,kBAAkB,EAA0C,MAAM,iCAAiC,CAAC;AAElH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AACD,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAmID;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,kBAAkB,GAAG,IAAI,GAAG,SAAS,KAAG,MAU/E,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,GAAI,aAAa;IAC5D,YAAY,EAAE,gBAAgB,EAAE,CAAC;CACpC,KAAG,iBAAiB,EAoDpB,CAAC;AAEF,UAAU,cAAc;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,QAAA,MAAM,QAAQ,GAAI,4BAA4B,cAAc,sBAyU3D,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAwBxB,OAAO,KAAsC,MAAM,OAAO,CAAC;AA8W3D,QAAA,MAAM,QAAQ,GAAI;;CAAc,sBAmV/B,CAAC;AAEF,eAAe,QAAQ,CAAC"}