@rh-support/troubleshoot 2.6.296 → 2.6.299

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 (97) hide show
  1. package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.d.ts.map +1 -1
  2. package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.js +4 -7
  3. package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
  4. package/lib/esm/components/CaseEditView/Case.js +42 -12
  5. package/lib/esm/components/CaseEditView/CaseDetailsTabs.d.ts.map +1 -1
  6. package/lib/esm/components/CaseEditView/CaseDetailsTabs.js +17 -7
  7. package/lib/esm/components/CaseEditView/CaseOverview/CaseStatus.d.ts +1 -2
  8. package/lib/esm/components/CaseEditView/CaseOverview/CaseStatus.d.ts.map +1 -1
  9. package/lib/esm/components/CaseEditView/CaseOverview/CaseStatus.js +8 -6
  10. package/lib/esm/components/CaseEditView/CaseOverview/index.d.ts.map +1 -1
  11. package/lib/esm/components/CaseEditView/CaseOverview/index.js +17 -12
  12. package/lib/esm/components/CaseEditView/ConfirmationModals/ReopenCaseModal.d.ts +1 -3
  13. package/lib/esm/components/CaseEditView/ConfirmationModals/ReopenCaseModal.d.ts.map +1 -1
  14. package/lib/esm/components/CaseEditView/ConfirmationModals/ReopenCaseModal.js +3 -4
  15. package/lib/esm/components/CaseEditView/RequestRemoteSession/ESSRemoteSessionModal.d.ts.map +1 -1
  16. package/lib/esm/components/CaseEditView/RequestRemoteSession/ESSRemoteSessionModal.js +4 -7
  17. package/lib/esm/components/CaseEditView/RequestRemoteSession/NewEssTermsModal.d.ts.map +1 -1
  18. package/lib/esm/components/CaseEditView/RequestRemoteSession/NewEssTermsModal.js +4 -30
  19. package/lib/esm/components/CaseEditView/RequestRemoteSession/RemoteSessionAgreementModal.d.ts.map +1 -1
  20. package/lib/esm/components/CaseEditView/RequestRemoteSession/RemoteSessionAgreementModal.js +4 -30
  21. package/lib/esm/components/CaseEditView/RequestRemoteSession/remoteSessionUtils.d.ts +3 -0
  22. package/lib/esm/components/CaseEditView/RequestRemoteSession/remoteSessionUtils.d.ts.map +1 -0
  23. package/lib/esm/components/CaseEditView/RequestRemoteSession/remoteSessionUtils.js +22 -0
  24. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts +4 -2
  25. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts.map +1 -1
  26. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.js +110 -148
  27. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.d.ts +15 -0
  28. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.d.ts.map +1 -0
  29. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.js +19 -0
  30. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useCommentDrafts.d.ts +17 -0
  31. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useCommentDrafts.d.ts.map +1 -0
  32. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useCommentDrafts.js +49 -0
  33. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts +6 -2
  34. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
  35. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +147 -241
  36. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/CaseHistory.d.ts.map +1 -1
  37. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/CaseHistory.js +3 -1
  38. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.css +4 -4
  39. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.d.ts +35 -3
  40. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.d.ts.map +1 -1
  41. package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.js +63 -224
  42. package/lib/esm/components/CaseEditView/Tabs/CaseSummary/CaseSummary.d.ts.map +1 -1
  43. package/lib/esm/components/CaseEditView/Tabs/CaseSummary/CaseSummary.js +7 -2
  44. package/lib/esm/components/CaseEditView/Tabs/RMEEscalations/RMEEscalationList.d.ts.map +1 -1
  45. package/lib/esm/components/CaseEditView/Tabs/RMEEscalations/RMEEscalationList.js +4 -7
  46. package/lib/esm/components/CaseManagement/Cep.d.ts.map +1 -1
  47. package/lib/esm/components/CaseManagement/Cep.js +4 -7
  48. package/lib/esm/components/ProductSelector/NewProductVersionSelector.d.ts.map +1 -1
  49. package/lib/esm/components/ProductSelector/NewProductVersionSelector.js +18 -4
  50. package/lib/esm/components/UpdateSeverityModal/UpdateSeverityModal.d.ts.map +1 -1
  51. package/lib/esm/components/UpdateSeverityModal/UpdateSeverityModal.js +4 -7
  52. package/lib/esm/components/shared/usePostComment.d.ts.map +1 -1
  53. package/lib/esm/components/shared/usePostComment.js +6 -10
  54. package/lib/esm/components/wizardLayout/GlobalTroubleshootEffects.d.ts.map +1 -1
  55. package/lib/esm/components/wizardLayout/GlobalTroubleshootEffects.js +0 -2
  56. package/lib/esm/hooks/useCaseComments/caseCommentMutation.d.ts +4 -0
  57. package/lib/esm/hooks/useCaseComments/caseCommentMutation.d.ts.map +1 -0
  58. package/lib/esm/hooks/useCaseComments/caseCommentMutation.js +12 -0
  59. package/lib/esm/hooks/useCaseComments/caseCommentsQuery.d.ts +4 -0
  60. package/lib/esm/hooks/useCaseComments/caseCommentsQuery.d.ts.map +1 -0
  61. package/lib/esm/hooks/useCaseComments/caseCommentsQuery.js +55 -0
  62. package/lib/esm/hooks/useCaseComments/index.d.ts +7 -0
  63. package/lib/esm/hooks/useCaseComments/index.d.ts.map +1 -0
  64. package/lib/esm/hooks/useCaseComments/index.js +5 -0
  65. package/lib/esm/hooks/useCaseComments/mapCaseComment.d.ts +25 -0
  66. package/lib/esm/hooks/useCaseComments/mapCaseComment.d.ts.map +1 -0
  67. package/lib/esm/hooks/useCaseComments/mapCaseComment.js +66 -0
  68. package/lib/esm/hooks/useCaseComments/types.d.ts +80 -0
  69. package/lib/esm/hooks/useCaseComments/types.d.ts.map +1 -0
  70. package/lib/esm/hooks/useCaseComments/types.js +1 -0
  71. package/lib/esm/hooks/useCaseComments/useCaseComments.d.ts +16 -0
  72. package/lib/esm/hooks/useCaseComments/useCaseComments.d.ts.map +1 -0
  73. package/lib/esm/hooks/useCaseComments/useCaseComments.js +25 -0
  74. package/lib/esm/hooks/useCaseComments/useCreateCaseComment.d.ts +19 -0
  75. package/lib/esm/hooks/useCaseComments/useCreateCaseComment.d.ts.map +1 -0
  76. package/lib/esm/hooks/useCaseComments/useCreateCaseComment.js +33 -0
  77. package/lib/esm/hooks/useCaseHistory.d.ts +26 -0
  78. package/lib/esm/hooks/useCaseHistory.d.ts.map +1 -0
  79. package/lib/esm/hooks/useCaseHistory.js +98 -0
  80. package/lib/esm/models/caseHistory.d.ts +80 -0
  81. package/lib/esm/models/caseHistory.d.ts.map +1 -0
  82. package/lib/esm/models/caseHistory.js +1 -0
  83. package/lib/esm/reducers/CaseConstNTypes.d.ts +0 -1
  84. package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
  85. package/lib/esm/reducers/CaseConstNTypes.js +0 -1
  86. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts +0 -2
  87. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts.map +1 -1
  88. package/lib/esm/reducers/CaseDiscussionTabReducer.js +1 -28
  89. package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
  90. package/lib/esm/reducers/CaseReducer.js +14 -4
  91. package/lib/esm/utils/TimelineUtils.d.ts +41 -0
  92. package/lib/esm/utils/TimelineUtils.d.ts.map +1 -0
  93. package/lib/esm/utils/TimelineUtils.js +134 -0
  94. package/lib/esm/utils/caseHistoryUtils.d.ts +66 -0
  95. package/lib/esm/utils/caseHistoryUtils.d.ts.map +1 -0
  96. package/lib/esm/utils/caseHistoryUtils.js +165 -0
  97. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAQ7F,OAAO,EAAkB,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAsB5F,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,WAAW,EAAE,CAAC;CACjC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,qBA+iBxC"}
1
+ {"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAMpF,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAqB5E,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAIrC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,WAAW,EAAE,CAAC;CACjC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,qBA4VxC"}
@@ -7,104 +7,92 @@ 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 { 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';
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';
17
16
  import isEmpty from 'lodash/isEmpty';
18
17
  import isEqual from 'lodash/isEqual';
19
- import uniqBy from 'lodash/uniqBy';
20
- import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
21
- import { useDropzone } from 'react-dropzone';
18
+ import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
22
19
  import { Trans, useTranslation } from 'react-i18next';
23
20
  import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
24
- import { CaseDetailsCacheNamespaces } from '../../../../enums/cache';
21
+ import { useCreateCaseComment } from '../../../../hooks/useCaseComments';
25
22
  import { useCaseUpdateErrorMessage } from '../../../../hooks/useCaseUpdateErrorMessage';
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';
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';
33
36
  import { PDFContext } from '../../PDFContainer';
34
- import { useMarkdownFileUploader } from './PostComment/useMarkdownFileUploader';
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';
35
41
  import { VerifyCaseStatusModal } from './VerifyCaseStatusModal/VerifyCaseStatusModal';
36
42
  export function PostComment(props) {
37
- var _a, _b;
43
+ var _a;
38
44
  const { t } = useTranslation();
39
45
  const caseUpdateError = useCaseUpdateErrorMessage();
40
46
  let { caseNumber } = props;
41
47
  const [isTextAreaFocused, setIsTextAreaFocused] = useState(false);
42
- const canAddAttachments = ability.can(resourceActions.PATCH, resources.CASE_CREATE, CaseListFields.ATTACHMENTS);
43
48
  const canPostPrivateComments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.POST_PRIVATE_COMMENT);
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 || '');
49
+ const { createComment, loading: isPostingComment } = useCreateCaseComment();
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);
56
51
  const [commentType, setCommentType] = useState(EditorMode.PLAIN);
57
52
  const [commentSignature, setCommentSignature] = useState('');
53
+ const [commentText, setCommentText] = useState(props.commentText || '');
58
54
  const { isExportingPDF } = useContext(PDFContext);
59
55
  const { getCommentTypeFromPreference, getCommentSignature } = useUserPreferences();
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);
75
- }
76
- });
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]);
77
62
  useEffect(() => {
78
- userOriginalCommentPrefs();
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
+ });
78
+ }
79
+ loadPrefs();
79
80
  // eslint-disable-next-line react-hooks/exhaustive-deps
80
81
  }, []);
81
82
  const [isModalOpen, setIsModalOpen] = useState(false);
82
83
  const [cssCommentAgreed, setCssCommentAgreed] = useState(false);
83
- const [isProcessing, setIsProcessing] = useState(isPostingComment || isUploadingAttachments);
84
+ const [isProcessing, setIsProcessing] = useState(false);
84
85
  const { globalMetadataState: { loggedInUser, loggedInUserRights, loggedInUsersAccount }, } = useContext(GlobalMetadataStateContext);
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) => ({
86
+ const { status, caseSalesforceId } = useCaseSelector((state) => ({
91
87
  status: state.caseDetails.status,
92
- contactSSOName: state.caseDetails.contactSSOName,
93
- selectedNotificationContacts: state.selectedNotificationContacts,
94
- selectedAccountDetails: state.selectedAccountDetails,
88
+ caseSalesforceId: state.caseDetails.id,
95
89
  }), isEqual);
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);
90
+ const isConfirmedStateSideSupport = (_a = loggedInUsersAccount === null || loggedInUsersAccount === void 0 ? void 0 : loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.hasConfirmedStatesideSupport;
98
91
  const caseDispatch = useCaseDispatch();
99
92
  const [isCommentTooLong, setIsCommentTooLong] = useState(false);
100
93
  const canEditCase = useCanEditCase();
101
94
  const componentRef = useRef(null);
102
95
  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
108
96
  const resetIsPublic = useCallback(() => setIsPublic(props.defaultIsPublic === null ? true : props.defaultIsPublic), [props.defaultIsPublic]);
109
97
  const previousDefaultIsPublic = usePrevious(props.defaultIsPublic);
110
98
  useEffect(() => {
@@ -112,99 +100,107 @@ export function PostComment(props) {
112
100
  return;
113
101
  props.defaultIsPublic === null ? resetIsPublic() : setIsPublic(props.defaultIsPublic);
114
102
  }, [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
117
103
  const textAreaRef = useCallback((node) => {
118
- if (node !== null &&
104
+ const isReplyMatch = node !== null &&
119
105
  props.commentText &&
120
106
  props.commentCreator &&
121
107
  commentText &&
122
- commentText === getReplyText(props.commentText, props.commentCreator)) {
123
- node.scrollTop = node.scrollHeight;
124
- node.focus();
125
- }
108
+ commentText === getReplyText(props.commentText, props.commentCreator);
109
+ if (!isReplyMatch)
110
+ return;
111
+ node.scrollTop = node.scrollHeight;
112
+ node.focus();
126
113
  },
127
114
  // eslint-disable-next-line react-hooks/exhaustive-deps
128
115
  [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
+ });
129
126
  const resetCommentSection = () => __awaiter(this, void 0, void 0, function* () {
127
+ var _a;
130
128
  setCommentText('');
131
129
  setIsTextAreaFocused(false);
132
130
  resetIsPublic();
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}` || '');
131
+ yield clearDraft();
132
+ (_a = props.onCommentClear) === null || _a === void 0 ? void 0 : _a.call(props);
133
+ setCommentText(commentSignature ? `\n ${commentSignature}` : '');
140
134
  });
141
- const resetAttachmentSection = () => {
142
- resetAttachment(dispatchToAttachmentReducer);
143
- };
144
135
  const onCancelClick = () => {
145
136
  resetCommentSection();
146
- resetAttachmentSection();
147
- cancelFileUpload();
148
137
  };
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]);
162
138
  const onCommentTextChange = (value, mode) => __awaiter(this, void 0, void 0, function* () {
163
- setCommentType(mode);
164
- setCommentText(value);
165
- debouncedCacheSave(value, mode, isPublic);
139
+ setCommentType(mode !== null && mode !== void 0 ? mode : commentType);
140
+ setCommentText(value !== null && value !== void 0 ? value : '');
141
+ saveDraft(value, mode, isPublic);
166
142
  });
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]);
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());
178
166
  useEffect(() => {
167
+ var _a;
179
168
  if (isCommentEmpty) {
180
- props.onCommentClear && props.onCommentClear();
169
+ (_a = props.onCommentClear) === null || _a === void 0 ? void 0 : _a.call(props);
181
170
  }
182
171
  // eslint-disable-next-line react-hooks/exhaustive-deps
183
172
  }, [commentText]);
184
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
185
173
  const onPostComment = () => __awaiter(this, void 0, void 0, function* () {
174
+ var _a;
186
175
  if (canEditCase.alert())
187
176
  return;
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
- }
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);
208
204
  }
209
205
  });
210
206
  const handleCheckboxToggle = () => {
@@ -214,10 +210,11 @@ export function PostComment(props) {
214
210
  return commentText.trim() === commentSignature;
215
211
  }
216
212
  const isPostCommentDisabled = isProcessing || !commentText || isCommentSignatureMatch();
217
- const isFileUploadDisabled = isConfirmedStateSideSupport && !cssCommentAgreed;
218
- const onFileUploadClick = () => {
219
- ToastNotification.addInfoMessage(t('Uploading Attachment(s)'));
220
- };
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
+ */
221
218
  const getReplyText = (replyText, commentCreator) => {
222
219
  const person = t(`(replying to {{commentCreator}}) \n`, { commentCreator });
223
220
  const reply = replyText
@@ -226,103 +223,29 @@ export function PostComment(props) {
226
223
  .reduce((acc, line) => (acc += '> ' + line + '\n'), person);
227
224
  return reply;
228
225
  };
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
- };
242
226
  useEffect(() => {
243
- if (!props.commentText || !props.commentCreator) {
227
+ if (!props.commentText || !props.commentCreator)
244
228
  return;
245
- }
246
229
  const reply = getReplyText(props.commentText, props.commentCreator);
247
230
  if (reply.includes(commentSignature)) {
248
231
  setCommentText(reply);
249
232
  }
250
233
  else {
251
- addCommentSignature(reply);
234
+ applySignature(reply);
252
235
  }
253
236
  // eslint-disable-next-line react-hooks/exhaustive-deps
254
237
  }, [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]);
284
238
  const onTextAreaBlur = () => {
285
- !commentText && setIsTextAreaFocused(false);
239
+ if (!commentText)
240
+ setIsTextAreaFocused(false);
286
241
  };
287
242
  const onCommentExceedCharsLimit = (lengthExceededNew) => {
288
243
  if (isCommentTooLong !== lengthExceededNew)
289
244
  setIsCommentTooLong(lengthExceededNew);
290
245
  };
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
324
246
  const isReplyDisabled = () => {
325
- let parsedPassedReply = getReplyText(passedReply, props.commentCreator);
247
+ var _a;
248
+ let parsedPassedReply = getReplyText(passedReply !== null && passedReply !== void 0 ? passedReply : '', (_a = props.commentCreator) !== null && _a !== void 0 ? _a : '');
326
249
  return (parsedPassedReply === null || parsedPassedReply === void 0 ? void 0 : parsedPassedReply.trim()) === (commentText === null || commentText === void 0 ? void 0 : commentText.trim());
327
250
  };
328
251
  const isSubmitDisabled = isReplyDisabled() ||
@@ -330,20 +253,10 @@ export function PostComment(props) {
330
253
  isPostCommentDisabled ||
331
254
  (isConfirmedStateSideSupport && !cssCommentAgreed);
332
255
  return (React.createElement("div", { className: `pf-v6-u-mb-md ${isExportingPDF ? 'hide-in-pdf' : ''}`, ref: componentRef },
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
- } }),
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" }),
347
260
  isConfirmedStateSideSupport && (React.createElement("div", { className: "pf-v6-u-mt-md pf-v6-u-mb-lg" },
348
261
  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) }),
349
262
  React.createElement("label", { htmlFor: "css-case-comment-agreement", className: "pf-v6-u-font-weight-normal pf-v6-u-font-size-sm" },
@@ -353,15 +266,8 @@ export function PostComment(props) {
353
266
  isModalOpen && loggedInUserRights.data.isInternal() && isPublic && (React.createElement(VerifyCaseStatusModal, { onClose: onCancel, onConfirm: onConfirm, isUpdating: isPostingComment, caseNumber: props.caseNumber })),
354
267
  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" },
355
268
  React.createElement(Trans, null, "Submit")),
356
- canAddAttachments &&
357
- (isPublic && canPostPrivateComments ? (React.createElement(Tooltip, { content: t('You can attach files privately') }, fileUploadButton)) : (fileUploadButton)),
358
269
  React.createElement(Button, { className: "secondary-button-pill", "data-tracking-id": "postcomment-cancel-button", type: "button", variant: ButtonVariant.link, onClick: onCancelClick, isDisabled: isPostCommentDisabled },
359
270
  React.createElement(Trans, null, "Cancel")),
360
271
  canPostPrivateComments && (React.createElement("span", { className: "post-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') }))));
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" })))))));
367
273
  }
@@ -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;AAI1B,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,MAAM,sBAMjC,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;AAK1B,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,MAAM,sBAQjC,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
+ import { useCaseSelector } from '../../../../context/CaseContext';
2
3
  import Timeline from './Timeline';
3
4
  const CaseHistory = (props) => {
5
+ const sfdcCaseId = useCaseSelector((state) => { var _a; return (_a = state.caseDetails) === null || _a === void 0 ? void 0 : _a.id; });
4
6
  return (React.createElement("div", { className: "pf-v6-u-p-sm" },
5
- React.createElement(Timeline, { caseNumber: props.caseNumber })));
7
+ React.createElement(Timeline, { caseNumber: props.caseNumber, sfdcCaseId: sfdcCaseId !== null && sfdcCaseId !== void 0 ? sfdcCaseId : '' })));
6
8
  };
7
9
  export default CaseHistory;
@@ -121,8 +121,8 @@
121
121
 
122
122
  .timeline-avatar {
123
123
  position: absolute;
124
- left: calc(20% + 15px);
125
- transform: translateX(-91%);
124
+ left: calc(20% + 2.5px);
125
+ transform: translateX(-50%);
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% + 18px);
138
- transform: translateX(-195%);
137
+ left: calc(20% + 2.5px);
138
+ transform: translateX(-50%);
139
139
  top: 25px;
140
140
  }
141
141
 
@@ -1,7 +1,39 @@
1
1
  import './Timeline.css';
2
2
  import React from 'react';
3
- declare const Timeline: ({ caseNumber }: {
4
- caseNumber: any;
5
- }) => React.JSX.Element;
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;
6
38
  export default Timeline;
7
39
  //# 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;AAwBxB,OAAO,KAAsC,MAAM,OAAO,CAAC;AA8W3D,QAAA,MAAM,QAAQ,GAAI;;CAAc,sBAmV/B,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;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"}