@rh-support/troubleshoot 2.6.303 → 2.6.304

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 (42) hide show
  1. package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
  2. package/lib/esm/components/CaseEditView/Case.js +5 -17
  3. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseAttachment.d.ts.map +1 -1
  4. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseAttachment.js +69 -21
  5. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts.map +1 -1
  6. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.js +53 -72
  7. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useMarkdownFileUploader.d.ts +1 -2
  8. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useMarkdownFileUploader.d.ts.map +1 -1
  9. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useMarkdownFileUploader.js +13 -8
  10. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts +2 -0
  11. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
  12. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +63 -26
  13. package/lib/esm/components/CaseInformation/FileDiag.d.ts.map +1 -1
  14. package/lib/esm/components/CaseInformation/FileDiag.js +10 -3
  15. package/lib/esm/components/ConfirmationModals/NoAttachmentSelectedModal.d.ts.map +1 -1
  16. package/lib/esm/components/ConfirmationModals/NoAttachmentSelectedModal.js +5 -3
  17. package/lib/esm/components/SubmitCase/SubmitCase.d.ts.map +1 -1
  18. package/lib/esm/components/SubmitCase/SubmitCase.js +1 -1
  19. package/lib/esm/components/shared/fileUpload/FileUploader.d.ts.map +1 -1
  20. package/lib/esm/components/shared/fileUpload/FileUploader.js +1 -1
  21. package/lib/esm/components/shared/fileUpload/WidgetFileUploader.d.ts.map +1 -1
  22. package/lib/esm/components/shared/fileUpload/WidgetFileUploader.js +2 -2
  23. package/lib/esm/components/shared/fileUpload/fileSelectors/FileSelectorButton.d.ts +1 -1
  24. package/lib/esm/components/shared/fileUpload/fileSelectors/FileSelectorButton.d.ts.map +1 -1
  25. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts +8 -7
  26. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts.map +1 -1
  27. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.js +39 -48
  28. package/lib/esm/components/shared/fileUpload/types/index.d.ts +2 -1
  29. package/lib/esm/components/shared/fileUpload/types/index.d.ts.map +1 -1
  30. package/lib/esm/components/shared/fileUpload/useFileUploader.d.ts +2 -2
  31. package/lib/esm/components/shared/fileUpload/useFileUploader.d.ts.map +1 -1
  32. package/lib/esm/components/shared/fileUpload/useFileUploader.js +38 -14
  33. package/lib/esm/hooks/useS3Upload.d.ts +5 -4
  34. package/lib/esm/hooks/useS3Upload.d.ts.map +1 -1
  35. package/lib/esm/hooks/useS3Upload.js +25 -30
  36. package/lib/esm/reducers/CaseDetailsPageReducer.d.ts +2 -1
  37. package/lib/esm/reducers/CaseDetailsPageReducer.d.ts.map +1 -1
  38. package/lib/esm/reducers/CaseDetailsPageReducer.js +12 -4
  39. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts +2 -1
  40. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts.map +1 -1
  41. package/lib/esm/reducers/CaseDiscussionTabReducer.js +11 -4
  42. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAS,mBAAmB,EAAiD,MAAM,kBAAkB,CAAC;AAoB7G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,MAAM,qBA+PzC"}
1
+ {"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAS,mBAAmB,EAAiD,MAAM,kBAAkB,CAAC;AAmB7G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,MAAM,qBA+PzC"}
@@ -20,10 +20,7 @@ import { Route, Switch, useLocation, useParams, useRouteMatch } from 'react-rout
20
20
  import { useCaseDispatch, useCaseSelector } from '../../context/CaseContext';
21
21
  import { useCaseDetailsPageDispatchContext } from '../../context/CaseDetailsPageContext';
22
22
  import { CaseReducerConstants } from '../../reducers/CaseConstNTypes';
23
- import {
24
- // TODO: Re-enable after GraphQL migration
25
- // fetchAttachments,
26
- fetchCaseEscalations,
23
+ import { fetchAttachments, fetchCaseEscalations,
27
24
  // fetchExternalTrackers,
28
25
  // fetchFeedbacks,
29
26
  } from '../../reducers/CaseDetailsPageReducer';
@@ -58,11 +55,7 @@ export default function Case(props) {
58
55
  // CaseDetailsFields.CASE_DETAILS_EXTERNAL_TRACKER
59
56
  // );
60
57
  // TODO: Re-enable after GraphQL migration of attachments
61
- // const canSeeAttachments = ability.can(
62
- // resourceActions.PATCH,
63
- // resources.CASE_DETAILS,
64
- // CaseDetailsFields.CASE_DETAILS_SEE_ATTACHMENTS
65
- // );
58
+ const canSeeAttachments = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEE_ATTACHMENTS);
66
59
  const canSeeRMEs = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_RMES);
67
60
  const { product, isFetchingCaseDetails, isFetchingCaseDetailsError, caseDetailsError, selectedAccountDetails } = useCaseSelector((state) => ({
68
61
  product: state.caseDetails.product,
@@ -132,14 +125,9 @@ export default function Case(props) {
132
125
  if (canSeeRMEs && (caseDetails === null || caseDetails === void 0 ? void 0 : caseDetails.id)) {
133
126
  fetchCaseEscalations((action) => currentCaseRef.current === targetCaseNumber && caseDetailsPageDispatch(action), caseDetails.id, apolloClient);
134
127
  }
135
- // TODO: Re-enable after GraphQL migration of attachments
136
- // if (canSeeAttachments) {
137
- // fetchAttachments(
138
- // (action) => currentCaseRef.current === targetCaseNumber && caseDetailsPageDispatch(action),
139
- // targetCaseNumber,
140
- // loggedInUsersAccount.data.secureSupport!
141
- // );
142
- // }
128
+ if (canSeeAttachments) {
129
+ fetchAttachments((action) => currentCaseRef.current === targetCaseNumber && caseDetailsPageDispatch(action), targetCaseNumber, apolloClient, caseDetails === null || caseDetails === void 0 ? void 0 : caseDetails.id);
130
+ }
143
131
  // TODO: Re-enable after GraphQL migration of external trackers
144
132
  // if (canSeeExternalTracker) {
145
133
  // fetchExternalTrackers(
@@ -1 +1 @@
1
- {"version":3,"file":"CaseAttachment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseAttachment.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAexE,OAAO,KAAuC,MAAM,OAAO,CAAC;AAS5D,UAAU,MAAM;IACZ,UAAU,EAAE,WAAW,CAAC;IACxB,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,KAAK,IAAI,CAAC;IACzE,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,kBAAkB,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChH;AAED,QAAA,MAAM,cAAc,4EAqPlB,CAAC;AAEH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"CaseAttachment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseAttachment.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAsBxE,OAAO,KAAuC,MAAM,OAAO,CAAC;AAS5D,UAAU,MAAM;IACZ,UAAU,EAAE,WAAW,CAAC;IACxB,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,KAAK,IAAI,CAAC;IACzE,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,kBAAkB,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChH;AAED,QAAA,MAAM,cAAc,4EA4RlB,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -7,13 +7,15 @@ 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 { caseAttachments, kase } from '@cee-eng/hydrajs';
10
+ import { useApolloClient } from '@apollo/client/react';
11
11
  import { Button, ButtonVariant, Icon, Tooltip, TooltipPosition } from '@patternfly/react-core';
12
12
  import PaperclipIcon from '@patternfly/react-icons/dist/js/icons/paperclip-icon';
13
13
  import { InlineEdit, LoadingIndicator, ToastNotification, useConfirmation, useCopyToClipboard, useFetch, } from '@rh-support/components';
14
- import { GlobalMetadataStateContext, useCanEditCase } from '@rh-support/react-context';
14
+ // TODO: Re-enable when secure support download restrictions are needed again
15
+ // import { GlobalMetadataStateContext, useCanEditCase } from '@rh-support/react-context';
16
+ import { useCanEditCase } from '@rh-support/react-context';
15
17
  import { ability, CaseDiscussionFields, resourceActions, resources } from '@rh-support/user-permissions';
16
- import { formatDateTime, humanizeSize } from '@rh-support/utils';
18
+ import { deleteCaseAttachment, formatDateTime, humanizeSize, updateCaseAttachmentDescriptionByGraphQL, } from '@rh-support/utils';
17
19
  import isEmpty from 'lodash/isEmpty';
18
20
  import React, { useContext, useRef, useState } from 'react';
19
21
  import { Trans, useTranslation } from 'react-i18next';
@@ -27,18 +29,35 @@ const CaseAttachment = React.forwardRef((props, ref) => {
27
29
  const { t } = useTranslation();
28
30
  const clipboardRef = useRef(null);
29
31
  const { clipboardText, copyToClipboard } = useCopyToClipboard(clipboardRef);
30
- const { request, isFetching: isDeleting } = useFetch(caseAttachments.deleteAttachment, { propgateErrors: true });
32
+ const { request, isFetching: isDeleting } = useFetch(deleteCaseAttachment, { propgateErrors: true });
31
33
  const canSeePrivateAttachments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.VIEW_PRIVATE_ATTACHMENT);
32
- const { globalMetadataState: { loggedInUsersAccount }, } = useContext(GlobalMetadataStateContext);
34
+ // TODO: Re-enable when secure support download restrictions are needed again
35
+ // const {
36
+ // globalMetadataState: { loggedInUsersAccount },
37
+ // } = useContext(GlobalMetadataStateContext);
33
38
  const [isCardIsDeleted, setIsCardIsDeleted] = useState(false); // adds a class name needed for anim when card is removed
34
39
  const { isExportingPDF } = useContext(PDFContext);
35
40
  const confirm = useConfirmation();
36
41
  const [attachmentDescription, setAttachmentDescription] = useState(props.attachment.description);
37
- const { request: updateDescriptionRequest, isFetching: isUpdating } = useFetch(kase.updateAttachment);
42
+ const [isUpdating, setIsUpdating] = useState(false);
43
+ const apolloClient = useApolloClient();
38
44
  const canEditCase = useCanEditCase();
39
45
  const onDescriptionSave = () => __awaiter(void 0, void 0, void 0, function* () {
40
- const updatedAttachment = yield updateDescriptionRequest(props.attachment.caseNumber, props.attachment.uuid, [{ path: 'description', op: 'update', value: attachmentDescription }], loggedInUsersAccount.data.secureSupport);
41
- props.onMetadataUpdate && props.onMetadataUpdate(props.attachment.uuid, updatedAttachment);
46
+ if (!apolloClient.mutate) {
47
+ ToastNotification.addDangerMessage(t('Failed to update attachment description'));
48
+ return;
49
+ }
50
+ setIsUpdating(true);
51
+ try {
52
+ const updatedAttachment = yield updateCaseAttachmentDescriptionByGraphQL(apolloClient, props.attachment, attachmentDescription);
53
+ props.onMetadataUpdate && props.onMetadataUpdate(props.attachment.uuid, updatedAttachment);
54
+ }
55
+ catch (_a) {
56
+ ToastNotification.addDangerMessage(t('Failed to update attachment description'));
57
+ }
58
+ finally {
59
+ setIsUpdating(false);
60
+ }
42
61
  });
43
62
  const onDescriptionChange = (event) => {
44
63
  if (canEditCase.alert())
@@ -61,7 +80,9 @@ const CaseAttachment = React.forwardRef((props, ref) => {
61
80
  "?")),
62
81
  });
63
82
  try {
64
- yield request(attachment.caseNumber, attachment.uuid, loggedInUsersAccount.data.secureSupport);
83
+ // TODO: Re-enable when delete API accepts isSecureSupport again
84
+ // await request!(attachment.caseNumber!, attachment.uuid!, loggedInUsersAccount.data.secureSupport);
85
+ yield request(attachment.caseNumber, attachment.uuid);
65
86
  ToastNotification.addSuccessMessage(t('Successfully deleted attachment: {{file}}', { file: attachment.fileName }));
66
87
  setIsCardIsDeleted(true);
67
88
  window.setTimeout(() => {
@@ -86,24 +107,51 @@ const CaseAttachment = React.forwardRef((props, ref) => {
86
107
  });
87
108
  };
88
109
  const renderAttachmentLink = () => {
89
- if (!loggedInUsersAccount.data.secureSupport) {
90
- if (isExportingPDF) {
91
- return (React.createElement("a", { href: props.attachment.link },
92
- React.createElement("span", null,
93
- props.attachment.fileName,
94
- " (",
95
- humanizeSize(props.attachment.size),
96
- ")")));
97
- }
98
- return (React.createElement(Button, { className: "attachment-download-btn", title: t('Download {{fileName}}', { fileName: props.attachment.fileName }), variant: ButtonVariant.link, onClick: onAttachmentDownloadClick, "data-tracking-id": "attachment-download-button" },
110
+ // TODO: Re-enable secure support download gating when needed again
111
+ // if (!loggedInUsersAccount.data.secureSupport) {
112
+ // if (isExportingPDF) {
113
+ // return (
114
+ // <a href={props.attachment.link}>
115
+ // <span>
116
+ // {props.attachment.fileName} ({humanizeSize(props.attachment.size)})
117
+ // </span>
118
+ // </a>
119
+ // );
120
+ // }
121
+ // return (
122
+ // <Button
123
+ // className="attachment-download-btn"
124
+ // title={t('Download {{fileName}}', { fileName: props.attachment.fileName })}
125
+ // variant={ButtonVariant.link}
126
+ // onClick={onAttachmentDownloadClick}
127
+ // data-tracking-id="attachment-download-button"
128
+ // >
129
+ // <span>
130
+ // {props.attachment.fileName} ({humanizeSize(props.attachment.size)})
131
+ // </span>
132
+ // </Button>
133
+ // );
134
+ // }
135
+ // return (
136
+ // <Tooltip
137
+ // position={TooltipPosition.top}
138
+ // content={t(`You don't have appropriate permissions to download the attachment`)}
139
+ // >
140
+ // <strong>
141
+ // {props.attachment.fileName} ({humanizeSize(props.attachment.size)})
142
+ // </strong>
143
+ // </Tooltip>
144
+ // );
145
+ if (isExportingPDF) {
146
+ return (React.createElement("a", { href: props.attachment.link },
99
147
  React.createElement("span", null,
100
148
  props.attachment.fileName,
101
149
  " (",
102
150
  humanizeSize(props.attachment.size),
103
151
  ")")));
104
152
  }
105
- return (React.createElement(Tooltip, { position: TooltipPosition.top, content: t(`You don't have appropriate permissions to download the attachment`) },
106
- React.createElement("strong", null,
153
+ return (React.createElement(Button, { className: "attachment-download-btn", title: t('Download {{fileName}}', { fileName: props.attachment.fileName }), variant: ButtonVariant.link, onClick: onAttachmentDownloadClick, "data-tracking-id": "attachment-download-button" },
154
+ React.createElement("span", null,
107
155
  props.attachment.fileName,
108
156
  " (",
109
157
  humanizeSize(props.attachment.size),
@@ -1 +1 @@
1
- {"version":3,"file":"CaseDiscussion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAcvE,OAAO,KAAoE,MAAM,OAAO,CAAC;AAwCzF,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAClD;AAOD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,MAAM,qBAmhBnD"}
1
+ {"version":3,"file":"CaseDiscussion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAkBvE,OAAO,KAAoE,MAAM,OAAO,CAAC;AAsCzF,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAClD;AAOD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,MAAM,qBA8hBnD"}
@@ -7,13 +7,12 @@ 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 chats, external trackers, attachments
11
- // import { ICaseChat, IExternalTrackerUpdate } from '@cee-eng/hydrajs/@types/api/public/case';
12
- // import { IAttachment } from '@cee-eng/hydrajs/@types/models/attachment';
10
+ import { useApolloClient } from '@apollo/client/react';
13
11
  import { MenuToggle, Select, SelectList, SelectOption } from '@patternfly/react-core';
14
- import { AlertMessage, AlertType, ErrorBoundary, LoadingIndicator } from '@rh-support/components';
12
+ import { AlertMessage, AlertType, ErrorBoundary, LoadingIndicator, ToastNotification } from '@rh-support/components';
15
13
  import { useGlobalStateContext } from '@rh-support/react-context';
16
- import { dtmTrackEventCaseStepEncountered, getUrlParsedParams, scrollIntoView } from '@rh-support/utils';
14
+ import { AbilityContext, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
15
+ import { downloadCaseAttachment, dtmTrackEventCaseStepEncountered, getUrlParsedParams, scrollIntoView, } from '@rh-support/utils';
17
16
  import cloneDeep from 'lodash/cloneDeep';
18
17
  import filter from 'lodash/filter';
19
18
  import findIndex from 'lodash/findIndex';
@@ -25,22 +24,13 @@ import { Trans, useTranslation } from 'react-i18next';
25
24
  import { useLocation } from 'react-router-dom';
26
25
  import { AutoSizer, CellMeasurer, CellMeasurerCache, List, WindowScroller } from 'react-virtualized';
27
26
  import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
27
+ import { useCaseDetailsPageDispatchContext, useCaseDetailsPageStateContext, } from '../../../../context/CaseDetailsPageContext';
28
28
  import { useCaseDiscussionTabDispatchContext, useCaseDiscussionTabStateContext, } from '../../../../context/CaseDiscussionTabContext';
29
- import { clearReplyComment, discussionSortOrderConst, DiscussionType, setCommentText, setDiscussions, setSort,
30
- // TODO: Re-enable after GraphQL migration
31
- // setFilter,
32
- // updateAttachment,
33
- // updateAttacmentsAfterRemoval,
34
- // updateCommentStateFeedback,
35
- // updateDiscussionStateAttachments,
36
- } from '../../../../reducers/CaseDiscussionTabReducer';
29
+ import { clearReplyComment, discussionSortOrderConst, DiscussionType, setCommentText, setDiscussions, setSort, updateAttachment, updateAttacmentsAfterRemoval, updateDiscussionStateAttachments, } from '../../../../reducers/CaseDiscussionTabReducer';
37
30
  import { setCaseState } from '../../../../reducers/CaseReducer';
38
- // TODO: Re-enable after GraphQL migration of attachments
39
- // import { AttachmentContextProvider } from '../../../shared/fileUpload/reducer/AttachmentReducerContext';
31
+ import { AttachmentContextProvider } from '../../../shared/fileUpload/reducer/AttachmentReducerContext';
40
32
  import { PDFContext } from '../../PDFContainer';
41
- // TODO: Re-enable after GraphQL migration
42
- // import CaseAttachment from './CaseAttachment';
43
- // import CaseChat from './CaseChat';
33
+ import CaseAttachment from './CaseAttachment';
44
34
  import CaseComments from './CaseComments';
45
35
  // import CaseExternalTrackerUpdate from './CaseExternalTrackerUpdate';
46
36
  import { CommentSearch } from './CommentSearch';
@@ -53,18 +43,24 @@ let cellMeasureCache = new CellMeasurerCache({
53
43
  });
54
44
  export default function CaseDiscussion(props) {
55
45
  const { t } = useTranslation();
56
- const { isPostingRemoteRequestCommentCompleted, product, version } = useCaseSelector((state) => ({
46
+ const { isPostingRemoteRequestCommentCompleted, product, version, caseSalesforceId } = useCaseSelector((state) => ({
57
47
  isPostingRemoteRequestCommentCompleted: state.isPostingRemoteRequestCommentCompleted,
58
48
  product: state.caseDetails.product,
59
49
  version: state.caseDetails.version,
50
+ caseSalesforceId: state.caseDetails.id,
60
51
  }), isEqual);
61
52
  const urlSearchParams = getUrlParsedParams(useLocation().search);
62
- const discussionIdFromUrl = urlSearchParams === null || urlSearchParams === void 0 ? void 0 : urlSearchParams.commentId;
53
+ const discussionIdFromUrl = ((urlSearchParams === null || urlSearchParams === void 0 ? void 0 : urlSearchParams.commentId) || (urlSearchParams === null || urlSearchParams === void 0 ? void 0 : urlSearchParams.attachmentId));
63
54
  const activeDiscussionElementRef = useRef(null);
64
- const { sort, allDiscussions, replyCommentText, replyCommentCreator } = useCaseDiscussionTabStateContext();
55
+ const { sort, discussionFiltersListState, allDiscussions, replyCommentText, replyCommentCreator } = useCaseDiscussionTabStateContext();
65
56
  const { globalMetadataState: { navBarRef }, } = useGlobalStateContext();
66
57
  const dispatchDiscussion = useCaseDiscussionTabDispatchContext();
58
+ const { caseDetailsPageState: { caseAttachmentHydra }, } = useCaseDetailsPageStateContext();
59
+ const dispatchCaseDetailsHydraAttachments = useCaseDetailsPageDispatchContext();
67
60
  const caseDispatch = useCaseDispatch();
61
+ const apolloClient = useApolloClient();
62
+ const ability = useContext(AbilityContext);
63
+ const canSeeAttachments = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEE_ATTACHMENTS);
68
64
  const { caseNumber } = props;
69
65
  const activeElementId = useRef(null);
70
66
  const listRef = React.useRef(null);
@@ -134,14 +130,15 @@ export default function CaseDiscussion(props) {
134
130
  }, [discussionIdFromUrl, allDiscussions, activeElementId.current]);
135
131
  useEffect(() => {
136
132
  if (!isExportingPDF) {
137
- setDiscussions(dispatchDiscussion, props.caseComments, [], // TODO: Re-enable chats after GraphQL migration
138
- [], // TODO: Re-enable attachments after GraphQL migration
139
- [], // TODO: Re-enable feedbacks after GraphQL migration
140
- [], // TODO: Re-enable external trackers after GraphQL migration
141
- [], false, false, false);
133
+ setDiscussions(dispatchDiscussion, props.caseComments, [], caseAttachmentHydra.data, [], [], discussionFiltersListState, false, false, canSeeAttachments);
142
134
  }
143
135
  // eslint-disable-next-line react-hooks/exhaustive-deps
144
- }, [props.caseComments]);
136
+ }, [props.caseComments, caseAttachmentHydra, canSeeAttachments]);
137
+ useEffect(() => {
138
+ if (!caseAttachmentHydra.isFetching && caseAttachmentHydra.isError) {
139
+ ToastNotification.addDangerMessage(t('There was an error loading attachments.'));
140
+ }
141
+ }, [caseAttachmentHydra.isFetching, caseAttachmentHydra.isError, t]);
145
142
  const onCommentAdded = () => __awaiter(this, void 0, void 0, function* () {
146
143
  try {
147
144
  yield props.refetchComments();
@@ -213,49 +210,30 @@ export default function CaseDiscussion(props) {
213
210
  activeElementId.current = '';
214
211
  }
215
212
  };
216
- // TODO: Re-enable after GraphQL migration of attachments
217
- // const onAttachmentRemove = (uuid_removed) => {
218
- // updateAttacmentsAfterRemoval(dispatchDiscussion, uuid_removed, allDiscussions, discussionFiltersListState);
219
- // };
220
- // TODO: Re-enable after GraphQL migration of attachments
221
- // const onAttachmentAdded = async () => {
222
- // ToastNotification.addSuccessMessage(t('Attachment(s) uploaded successfully'));
223
- // await updateDiscussionStateAttachments(
224
- // dispatchDiscussion,
225
- // caseNumber,
226
- // allDiscussions,
227
- // sort,
228
- // loggedInUsersAccount.data.secureSupport,
229
- // discussionFiltersListState,
230
- // dispatchCaseDetailsHydraAttachments
231
- // );
232
- // };
233
- // TODO: Re-enable after GraphQL migration of attachments
234
- // const onMetadataUpdate = (attachmentId: string, updatedAttachment) => {
235
- // updateAttachment(dispatchDiscussion, attachmentId, updatedAttachment, allDiscussions);
236
- // };
237
- // TODO: Re-enable after GraphQL migration of attachments
238
- // const downloadAttachment = async ({ caseNumber, uuid, name }) => {
239
- // const tempToastId = ToastNotification.addInfoMessage(t('Starting file download'));
240
- // try {
241
- // await caseAttachments.downloadAttachmentS3(
242
- // caseNumber,
243
- // uuid,
244
- // name,
245
- // false,
246
- // loggedInUsersAccount.data.secureSupport
247
- // );
248
- // } catch (e) {
249
- // ToastNotification.addDangerMessage(
250
- // t(`Could not download {{filename}}: {{error}}`, {
251
- // filename: name,
252
- // error: e?.message,
253
- // })
254
- // );
255
- // } finally {
256
- // tempToastId && ToastNotification.clearToast(tempToastId);
257
- // }
258
- // };
213
+ const onAttachmentRemove = (uuid_removed) => {
214
+ updateAttacmentsAfterRemoval(dispatchDiscussion, uuid_removed, allDiscussions, discussionFiltersListState);
215
+ };
216
+ const onAttachmentAdded = () => __awaiter(this, void 0, void 0, function* () {
217
+ yield updateDiscussionStateAttachments(dispatchDiscussion, caseNumber, allDiscussions, sort, discussionFiltersListState, dispatchCaseDetailsHydraAttachments, apolloClient, caseSalesforceId);
218
+ });
219
+ const onMetadataUpdate = (attachmentId, updatedAttachment) => {
220
+ updateAttachment(dispatchDiscussion, attachmentId, updatedAttachment, allDiscussions);
221
+ };
222
+ const downloadAttachment = ({ caseNumber: attachmentCaseNumber, uuid, name }) => {
223
+ const tempToastId = ToastNotification.addInfoMessage(t('Starting file download'));
224
+ try {
225
+ downloadCaseAttachment(attachmentCaseNumber, uuid, name);
226
+ }
227
+ catch (e) {
228
+ ToastNotification.addDangerMessage(t('Could not download {{filename}}: {{error}}', {
229
+ filename: name,
230
+ error: e === null || e === void 0 ? void 0 : e.message,
231
+ }));
232
+ }
233
+ finally {
234
+ tempToastId && ToastNotification.clearToast(tempToastId);
235
+ }
236
+ };
259
237
  useEffect(() => {
260
238
  if (discussionSectionWidth && shouldRenderRVComponent) {
261
239
  cellMeasureCache && cellMeasureCache.clearAll();
@@ -282,7 +260,9 @@ export default function CaseDiscussion(props) {
282
260
  const renderCaseCommentElement = (discussion) => {
283
261
  if (isEmpty(discussion) || isEmpty(discussion.item))
284
262
  return null;
285
- return (React.createElement("div", { "data-tracking-id": "discussion-elements", key: discussion.item.id }, discussion.discussionType === DiscussionType.COMMENT && (React.createElement(CaseComments, { caseNumber: caseNumber, ref: discussionIdFromUrl === discussion.item.id ? activeDiscussionElementRef : null, comment: discussion.item, onFeedBackUpdate: () => { }, feedback: discussion.feedback, accountNumber: props.accountNumber, onReply: onReply, showJumpToComment: !isEmpty(searchCommentText), onJumpToComment: onJumpToComment, downloadAttachment: () => { } }))));
263
+ return (React.createElement("div", { "data-tracking-id": "discussion-elements", key: discussion.item.id },
264
+ discussion.discussionType === DiscussionType.COMMENT && (React.createElement(CaseComments, { caseNumber: caseNumber, ref: discussionIdFromUrl === discussion.item.id ? activeDiscussionElementRef : null, comment: discussion.item, onFeedBackUpdate: () => { }, feedback: discussion.feedback, accountNumber: props.accountNumber, onReply: onReply, showJumpToComment: !isEmpty(searchCommentText), onJumpToComment: onJumpToComment, downloadAttachment: downloadAttachment })),
265
+ discussion.discussionType === DiscussionType.ATTACHMENT && (React.createElement(CaseAttachment, { attachment: discussion.item, onAttachmentRemove: onAttachmentRemove, onMetadataUpdate: onMetadataUpdate, showJumpToComment: !isEmpty(searchCommentText), onJumpToComment: onJumpToComment, downloadAttachment: downloadAttachment, ref: discussionIdFromUrl === discussion.item.id ? activeDiscussionElementRef : null }))));
286
266
  };
287
267
  const rowRenderer = ({ index, parent, key, style, }) => {
288
268
  const discussion = comuteSearchedComments[index];
@@ -354,7 +334,8 @@ export default function CaseDiscussion(props) {
354
334
  const onSortToggle = (toggleRef) => (React.createElement(MenuToggle, { ref: toggleRef, onClick: onSortToggleClick, isExpanded: isSortOpen, isFullWidth: true }, sort.name));
355
335
  return (React.createElement(React.Fragment, null,
356
336
  React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading post comment section') } },
357
- React.createElement(PostComment, { caseNumber: caseNumber, allDiscussions: allDiscussions, onCommentAdded: onCommentAdded, commentText: replyCommentText, onCommentClear: resetReplyComment, commentCreator: replyCommentCreator, defaultIsPublic: replyingToPrivateComment === null ? replyingToPrivateComment : !replyingToPrivateComment })),
337
+ React.createElement(AttachmentContextProvider, null,
338
+ React.createElement(PostComment, { caseNumber: caseNumber, allDiscussions: allDiscussions, onCommentAdded: onCommentAdded, onAttachmentAdded: onAttachmentAdded, onAttachmentRemove: onAttachmentRemove, commentText: replyCommentText, onCommentClear: resetReplyComment, commentCreator: replyCommentCreator, defaultIsPublic: replyingToPrivateComment === null ? replyingToPrivateComment : !replyingToPrivateComment }))),
358
339
  props.commentsLoading && allDiscussions.length === 0 && React.createElement(LoadingIndicator, { size: "sm" }),
359
340
  props.commentsError && allDiscussions.length === 0 && (React.createElement(AlertMessage, { variant: AlertType.DANGER, show: true, title: t('Failed to load comments. Try refreshing.') })),
360
341
  !props.commentsLoading && !props.commentsError && allDiscussions.length === 0 && (React.createElement(Trans, null, "No comments")),
@@ -2,10 +2,9 @@ import { IAttachment } from '@cee-eng/hydrajs/@types/models/attachment';
2
2
  interface IProps {
3
3
  onAttachmentAdded: () => void;
4
4
  caseNumber: string;
5
- secureSupport: boolean;
6
5
  }
7
6
  export declare const FILE_SIZE_LIMIT: number;
8
- export declare function useMarkdownFileUploader({ caseNumber, secureSupport, onAttachmentAdded }: IProps): {
7
+ export declare function useMarkdownFileUploader({ caseNumber, onAttachmentAdded }: IProps): {
9
8
  isMarkdownFileUploadInProgress: boolean;
10
9
  isDeletingFile: boolean;
11
10
  isUploadingFile: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useMarkdownFileUploader.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useMarkdownFileUploader.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAcxE,UAAU,MAAM;IACZ,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,eAAe,QAAkB,CAAC;AAE/C,wBAAgB,uBAAuB,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,EAAE,MAAM;;;;;;+BAyDpD,OAAO,CAAC,WAAW,CAAC;;EA2C/D"}
1
+ {"version":3,"file":"useMarkdownFileUploader.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useMarkdownFileUploader.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAexE,UAAU,MAAM;IACZ,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,eAAe,QAAkB,CAAC;AAE/C,wBAAgB,uBAAuB,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,MAAM;;;;;;+BA0DrC,OAAO,CAAC,WAAW,CAAC;;EA2C/D"}
@@ -7,28 +7,33 @@ 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 { caseAttachments } from '@cee-eng/hydrajs';
10
+ import { useApolloClient } from '@apollo/client/react';
11
11
  import { ToastNotification, useConfirmation, useFetch } from '@rh-support/components';
12
- import { pendoTrackEvent } from '@rh-support/utils';
12
+ import { deleteCaseAttachment, pendoTrackEvent } from '@rh-support/utils';
13
13
  import React, { useRef, useState } from 'react';
14
14
  import { Trans, useTranslation } from 'react-i18next';
15
+ import { useCaseSelector } from '../../../../../context/CaseContext';
15
16
  import { useCaseDiscussionTabDispatchContext, useCaseDiscussionTabStateContext, } from '../../../../../context/CaseDiscussionTabContext';
16
17
  import { useS3Upload } from '../../../../../hooks/useS3Upload';
17
18
  import { updateAttacmentsAfterRemoval } from '../../../../../reducers/CaseDiscussionTabReducer';
18
19
  import { markdownInlineFileSelectEvent } from '../../../../shared/Constants';
19
20
  export const FILE_SIZE_LIMIT = 2 * 1024 * 1000;
20
- export function useMarkdownFileUploader({ caseNumber, secureSupport, onAttachmentAdded }) {
21
+ export function useMarkdownFileUploader({ caseNumber, onAttachmentAdded }) {
21
22
  const [isMarkdownFileUploadInProgress, setIsMarkdownFileUploadinProgress] = useState(false);
22
- // We need one more state to check if user canceled current upload
23
- // Reason to use `useRef` as we need up to date state value in callback
24
23
  const isMarkdownFileUploadCanceled = useRef(false);
25
- const { request: deleteAttachmentRequest, isFetching: isDeletingFile } = useFetch(caseAttachments.deleteAttachment, {
24
+ const apolloClient = useApolloClient();
25
+ const { caseSalesforceId } = useCaseSelector((state) => ({
26
+ caseSalesforceId: state.caseDetails.id,
27
+ }));
28
+ const { request: deleteAttachmentRequest, isFetching: isDeletingFile } = useFetch(deleteCaseAttachment, {
26
29
  propgateErrors: true,
27
30
  });
28
31
  const { discussionFiltersListState, allDiscussions } = useCaseDiscussionTabStateContext();
29
32
  const dispatchDiscussion = useCaseDiscussionTabDispatchContext();
30
33
  const confirm = useConfirmation();
31
- const { uploadFile, isUploadingFile } = useS3Upload(caseNumber, secureSupport);
34
+ // TODO: Re-enable when Hydra/GraphQL attachment APIs support secure support again
35
+ // Previously: useS3Upload(caseNumber, secureSupport)
36
+ const { uploadFile, isUploadingFile } = useS3Upload(caseNumber, apolloClient, caseSalesforceId);
32
37
  const markdownFileUploadListener = (progress, abort) => {
33
38
  // If user canceled upload then don't enable uploading label and abort
34
39
  if (isMarkdownFileUploadCanceled.current) {
@@ -78,7 +83,7 @@ export function useMarkdownFileUploader({ caseNumber, secureSupport, onAttachmen
78
83
  });
79
84
  try {
80
85
  ToastNotification.addInfoMessage(t('Deleting attachment: {{file}}', { file: attachment.fileName }));
81
- yield deleteAttachmentRequest(attachment.caseNumber, attachment.uuid, secureSupport);
86
+ yield deleteAttachmentRequest(attachment.caseNumber, attachment.uuid);
82
87
  ToastNotification.addSuccessMessage(t('Successfully deleted attachment: {{file}}', { file: attachment.fileName }));
83
88
  updateAttacmentsAfterRemoval(dispatchDiscussion, attachment.uuid, allDiscussions, discussionFiltersListState);
84
89
  }
@@ -5,6 +5,8 @@ interface IProps {
5
5
  commentText?: string;
6
6
  commentCreator?: string;
7
7
  onCommentAdded?: () => Promise<void>;
8
+ onAttachmentAdded?: () => void;
9
+ onAttachmentRemove?: (uuid: string) => void;
8
10
  onCommentClear?: () => void;
9
11
  /**
10
12
  * Controls the initial visibility toggle state.
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAOpF,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAkB5E,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;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,WAAW,EAAE,CAAC;CACjC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,qBAuaxC"}