@rh-support/troubleshoot 2.6.306 → 2.6.309

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/CaseDetailsTabs.d.ts.map +1 -1
  2. package/lib/esm/components/CaseEditView/CaseDetailsTabs.js +25 -21
  3. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.d.ts.map +1 -1
  4. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.js +6 -1
  5. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseAttachment.js +1 -1
  6. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.d.ts.map +1 -1
  7. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.js +104 -83
  8. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CommentSearch.d.ts.map +1 -1
  9. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CommentSearch.js +3 -2
  10. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/DiscussionItemLink.d.ts.map +1 -1
  11. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/DiscussionItemLink.js +7 -1
  12. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/JumpAndCopyLink.d.ts.map +1 -1
  13. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/JumpAndCopyLink.js +8 -1
  14. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.d.ts +8 -3
  15. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.d.ts.map +1 -1
  16. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.js +11 -9
  17. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
  18. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +33 -17
  19. package/lib/esm/components/CaseInformation/CaseLabels.d.ts +3 -0
  20. package/lib/esm/components/CaseInformation/CaseLabels.d.ts.map +1 -0
  21. package/lib/esm/components/CaseInformation/CaseLabels.js +98 -0
  22. package/lib/esm/components/shared/fileUpload/FileLister.js +1 -1
  23. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts +11 -2
  24. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts.map +1 -1
  25. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.js +65 -9
  26. package/lib/esm/components/shared/fileUpload/reducer/AttachmentReducer.d.ts +5 -1
  27. package/lib/esm/components/shared/fileUpload/reducer/AttachmentReducer.d.ts.map +1 -1
  28. package/lib/esm/components/shared/fileUpload/reducer/AttachmentReducer.js +23 -1
  29. package/lib/esm/components/shared/fileUpload/types/index.d.ts +2 -0
  30. package/lib/esm/components/shared/fileUpload/types/index.d.ts.map +1 -1
  31. package/lib/esm/components/shared/fileUpload/useFileUploader.d.ts.map +1 -1
  32. package/lib/esm/components/shared/fileUpload/useFileUploader.js +7 -1
  33. package/lib/esm/css/case.css +12 -7
  34. package/lib/esm/hooks/useCaseComments/mapCaseComment.d.ts +1 -1
  35. package/lib/esm/hooks/useCaseComments/mapCaseComment.d.ts.map +1 -1
  36. package/lib/esm/hooks/useCaseComments/mapCaseComment.js +14 -3
  37. package/lib/esm/hooks/useCaseLabelLinkMutations.d.ts +21 -0
  38. package/lib/esm/hooks/useCaseLabelLinkMutations.d.ts.map +1 -0
  39. package/lib/esm/hooks/useCaseLabelLinkMutations.js +84 -0
  40. package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts.map +1 -1
  41. package/lib/esm/reducers/CaseDiscussionTabReducer.js +6 -2
  42. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"CaseDetailsTabs.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/CaseDetailsTabs.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AA6BlE,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACnD;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,qBAyT5C"}
1
+ {"version":3,"file":"CaseDetailsTabs.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/CaseDetailsTabs.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AA8BlE,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACnD;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,qBAoT5C"}
@@ -1,4 +1,4 @@
1
- import { Content, ContentVariants, Label, Popover, Tab, TabContent, Tabs, TabsComponent, TabTitleText, } from '@patternfly/react-core';
1
+ import { Content, ContentVariants, Popover, Tab, TabContent, Tabs, TabsComponent, TabTitleText, } from '@patternfly/react-core';
2
2
  import ExternalLinkAltIcon from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
3
3
  import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
4
4
  import { ErrorBoundary, LoadingIndicator } from '@rh-support/components';
@@ -16,7 +16,8 @@ import { useCaseComments } from '../../hooks/useCaseComments';
16
16
  import { PDFContext } from './PDFContainer';
17
17
  import CaseDetailsManagement from './Tabs/CaseDetails/CaseDetailsManagement';
18
18
  import CaseHistory from './Tabs/CaseHistory/CaseHistory';
19
- import { CaseSummary } from './Tabs/CaseSummary/CaseSummary';
19
+ // TODO: Re-enable AI Case Summary tab when ready
20
+ // import { CaseSummary } from './Tabs/CaseSummary/CaseSummary';
20
21
  // TODO: Uncomment when External Trackers has a functioning GraphQL endpoint
21
22
  // const RelatedTasks = React.lazy(
22
23
  // () => import(/* webpackChunkName: 'CaseBugzilla' */ './Tabs/RelatedTasks/RelatedTasks')
@@ -56,8 +57,13 @@ export function CaseDetailsTabs(props) {
56
57
  // resources.CASE_DETAILS,
57
58
  // CaseDetailsFields.CASE_DETAILS_BUGZILLAS
58
59
  // );
59
- const caseSummaryViewConfig = getConfigField(pcmConfig.data, 'is_case_summary_view_active', PCM_CONFIG_FIELD_TYPE.STRING);
60
- const isCaseSummaryViewActive = caseSummaryViewConfig === '1';
60
+ // TODO: Re-enable AI Case Summary tab when ready
61
+ // const caseSummaryViewConfig = getConfigField(
62
+ // pcmConfig.data,
63
+ // 'is_case_summary_view_active',
64
+ // PCM_CONFIG_FIELD_TYPE.STRING
65
+ // );
66
+ // const isCaseSummaryViewActive = caseSummaryViewConfig === '1';
61
67
  const { isExportingPDF, pdfOption } = useContext(PDFContext);
62
68
  const canSeeRMEs = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_RMES);
63
69
  const [selectedTab, setSelectedTab] = useState(CaseDetailsTabsEnum.DISCUSSION);
@@ -70,7 +76,8 @@ export function CaseDetailsTabs(props) {
70
76
  // TODO: Uncomment when External Trackers has a functioning GraphQL endpoint
71
77
  // const relatedTasksRef: React.MutableRefObject<HTMLDivElement> = useRef(null);
72
78
  const caseHistoryTabRef = useRef(null);
73
- const generateAiCaseSummaryTabRef = useRef(null);
79
+ // TODO: Re-enable AI Case Summary tab when ready
80
+ // const generateAiCaseSummaryTabRef: React.MutableRefObject<HTMLDivElement> = useRef(null);
74
81
  const tabsToRender = [];
75
82
  const handleTabClick = (_event, tabIndex) => {
76
83
  const index = Number(tabIndex);
@@ -146,17 +153,18 @@ export function CaseDetailsTabs(props) {
146
153
  ref: caseHistoryTabRef,
147
154
  component: React.createElement(CaseHistory, { caseNumber: caseNumber }),
148
155
  });
149
- !loggedInUsersAccount.data.secureSupport &&
150
- !loggedInUsersAccount.data.hasConfirmedStatesideSupport &&
151
- isCaseSummaryViewActive &&
152
- tabsToRender.push({
153
- 'data-tracking-id': 'generate-ai-case-summary-tab',
154
- title: CaseDetailsTabsEnum.GENERATE_AI_CASE_SUMMARY,
155
- key: 'generate ai case summary',
156
- routePath: 'generate-ai-case-summary',
157
- ref: generateAiCaseSummaryTabRef,
158
- component: React.createElement(CaseSummary, { caseNumber: caseNumber }),
159
- });
156
+ // TODO: Re-enable AI Case Summary tab when ready
157
+ // !loggedInUsersAccount.data.secureSupport &&
158
+ // !loggedInUsersAccount.data.hasConfirmedStatesideSupport &&
159
+ // isCaseSummaryViewActive &&
160
+ // tabsToRender.push({
161
+ // 'data-tracking-id': 'generate-ai-case-summary-tab',
162
+ // title: CaseDetailsTabsEnum.GENERATE_AI_CASE_SUMMARY,
163
+ // key: 'generate ai case summary',
164
+ // routePath: 'generate-ai-case-summary',
165
+ // ref: generateAiCaseSummaryTabRef,
166
+ // component: <CaseSummary caseNumber={caseNumber} />,
167
+ // });
160
168
  const getActiveTabKey = () => {
161
169
  if (!activeTab)
162
170
  return activeTabKey;
@@ -168,12 +176,8 @@ export function CaseDetailsTabs(props) {
168
176
  ? false
169
177
  : true;
170
178
  return (React.createElement("div", { className: "case-details-tabs", role: "region", ref: props.tabdRef },
171
- React.createElement(Tabs, { className: isExportingPDF ? 'hide-in-pdf' : '', activeKey: getActiveTabKey(), component: TabsComponent.nav, onSelect: handleTabClick, "aria-label": t('Case details tabs') }, tabsToRender.map((tab, index) => (React.createElement(Tab, { eventKey: index, tabContentRef: tab.ref, tabContentId: `pf-tab-${index}-${tab.title.split(' ')[0]}-tabpanel`, key: tab.title, href: `#${props.basePath}/${tab.routePath}`, "data-tracking-id": tab['data-tracking-id'], title: React.createElement(TabTitleText, { className: tab.title === CaseDetailsTabsEnum.GENERATE_AI_CASE_SUMMARY ||
172
- tab.title === CaseDetailsTabsEnum.HISTORY
173
- ? 'tab-title-with-badge'
174
- : undefined },
179
+ React.createElement(Tabs, { className: isExportingPDF ? 'hide-in-pdf' : '', activeKey: getActiveTabKey(), component: TabsComponent.nav, onSelect: handleTabClick, "aria-label": t('Case details tabs') }, tabsToRender.map((tab, index) => (React.createElement(Tab, { eventKey: index, tabContentRef: tab.ref, tabContentId: `pf-tab-${index}-${tab.title.split(' ')[0]}-tabpanel`, key: tab.title, href: `#${props.basePath}/${tab.routePath}`, "data-tracking-id": tab['data-tracking-id'], title: React.createElement(TabTitleText, { className: tab.title === CaseDetailsTabsEnum.HISTORY ? 'tab-title-with-badge' : undefined },
175
180
  React.createElement(Trans, null, tab.title),
176
- tab.title === CaseDetailsTabsEnum.GENERATE_AI_CASE_SUMMARY && (React.createElement(Label, { isCompact: true, variant: "outline", className: "preview-label" }, "Preview")),
177
181
  tab.title === CaseDetailsTabsEnum.HISTORY && (React.createElement(Popover, { "aria-label": "Track support case evolution with case history", triggerAction: "hover", bodyContent: React.createElement(React.Fragment, null,
178
182
  React.createElement("p", null, "Track support case evolution with case history"),
179
183
  React.createElement("a", { href: "https://access.redhat.com/articles/7120652", target: "_blank", rel: "noreferrer" },
@@ -1 +1 @@
1
- {"version":3,"file":"CaseDetailsManagement.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAkBvD,UAAU,MAAO,SAAQ,gBAAgB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,KAAK,EAAE,MAAM,qBAmE1D"}
1
+ {"version":3,"file":"CaseDetailsManagement.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAmBvD,UAAU,MAAO,SAAQ,gBAAgB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,KAAK,EAAE,MAAM,qBA0E1D"}
@@ -5,6 +5,7 @@ import React, { useContext, useState } from 'react';
5
5
  import { useCaseSelector } from '../../../../context/CaseContext';
6
6
  import { OwnerSelector } from '../../../AccountInfo/OwnerSelector';
7
7
  import CaseGroup from '../../../CaseInformation/CaseGroup';
8
+ import CaseLabels from '../../../CaseInformation/CaseLabels';
8
9
  import Fts from '../../../CaseInformation/Fts';
9
10
  // import { Cep } from '../../../CaseManagement/Cep';
10
11
  // import { RHAssociatesSelector } from '../../../CaseManagement/RHAssociatesSelector';
@@ -45,7 +46,11 @@ export default function CaseDetailsManagement(props) {
45
46
  React.createElement(CaseContactPhoneNumberAlert, { isConfirm: true }),
46
47
  canSeeInternalStatus && React.createElement(CaseInternalStatus, null),
47
48
  canSeeSBRGroups && React.createElement(CaseSbrGroups, null),
48
- React.createElement(CaseGroup, null),
49
+ React.createElement(Flex, { direction: { default: 'column', lg: 'row' } },
50
+ React.createElement(FlexItem, { flex: { default: 'flex_1' } },
51
+ React.createElement(CaseGroup, null)),
52
+ React.createElement(FlexItem, { flex: { default: 'flex_1' } },
53
+ React.createElement(CaseLabels, null))),
49
54
  React.createElement(CaseReferenceNumber, null),
50
55
  React.createElement(Fts, { inlineEditable: true }),
51
56
  React.createElement(SFDCUrl, null),
@@ -173,7 +173,7 @@ const CaseAttachment = React.forwardRef((props, ref) => {
173
173
  React.createElement("h4", null,
174
174
  React.createElement(Icon, { className: "pf-v6-u-mr-xs" },
175
175
  React.createElement(PaperclipIcon, null)),
176
- props.attachment.modifiedBy),
176
+ props.attachment.createdBy),
177
177
  React.createElement("time", { className: "text-right" }, formatDateTime(props.attachment.lastModifiedDate))),
178
178
  React.createElement("div", { className: "comment-body" },
179
179
  React.createElement(Trans, null, "Attached file"),
@@ -1 +1 @@
1
- {"version":3,"file":"CaseComments.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AA+BvE,OAAO,KAAkD,MAAM,OAAO,CAAC;AAQvE,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,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,YAAY,4EAiXhB,CAAC;AAEH,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"CaseComments.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AA4BvE,OAAO,KAAwC,MAAM,OAAO,CAAC;AAU7D,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,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,YAAY,4EA0VhB,CAAC;AAEH,eAAe,YAAY,CAAC"}
@@ -1,30 +1,30 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { publicApi } from '@cee-eng/hydrajs';
11
- import { encodeAngularBrackets, EventTypes, htmlEntitiesEncode, linkifyBZIDs, linkifyWithCaseIDs, parseCommentMarkdown, processRME, } from '@cee-eng/ui-toolkit';
12
- import { Icon, Tooltip, TooltipPosition } from '@patternfly/react-core';
13
- import FrownIcon from '@patternfly/react-icons/dist/js/icons/frown-icon';
14
- import MehIcon from '@patternfly/react-icons/dist/js/icons/meh-icon';
15
- import OutlinedFrownIcon from '@patternfly/react-icons/dist/js/icons/outlined-frown-icon';
16
- import OutlinedMehIcon from '@patternfly/react-icons/dist/js/icons/outlined-meh-icon';
17
- import OutlinedSmileIcon from '@patternfly/react-icons/dist/js/icons/outlined-smile-icon';
18
- import SmileIcon from '@patternfly/react-icons/dist/js/icons/smile-icon';
1
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
2
+ // import { ICommentFeedback } from '@cee-eng/hydrajs/@types/api/public/commentFeedback';
3
+ import { EventTypes, linkifyBZIDs, linkifyWithCaseIDs, parseCommentMarkdown, processRME } from '@cee-eng/ui-toolkit';
4
+ import { Icon } from '@patternfly/react-core';
5
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
6
+ // import { Tooltip, TooltipPosition } from '@patternfly/react-core';
7
+ // import FrownIcon from '@patternfly/react-icons/dist/js/icons/frown-icon';
8
+ // import MehIcon from '@patternfly/react-icons/dist/js/icons/meh-icon';
9
+ // import OutlinedFrownIcon from '@patternfly/react-icons/dist/js/icons/outlined-frown-icon';
10
+ // import OutlinedMehIcon from '@patternfly/react-icons/dist/js/icons/outlined-meh-icon';
11
+ // import OutlinedSmileIcon from '@patternfly/react-icons/dist/js/icons/outlined-smile-icon';
12
+ // import SmileIcon from '@patternfly/react-icons/dist/js/icons/smile-icon';
19
13
  import UserCircleIcon from '@patternfly/react-icons/dist/js/icons/user-circle-icon';
20
- import { EditorMode, LoadingIndicator, ToastNotification } from '@rh-support/components';
21
- import { AbilityContext, CaseDetailsFields, CaseDiscussionFields, resourceActions, resources, } from '@rh-support/user-permissions';
14
+ import { EditorMode } from '@rh-support/components';
15
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
16
+ // import { LoadingIndicator, ToastNotification } from '@rh-support/components';
17
+ import { AbilityContext,
18
+ // CaseDetailsFields, // TODO: Re-enable after GraphQL migration of feedback
19
+ CaseDiscussionFields, resourceActions, resources, } from '@rh-support/user-permissions';
22
20
  import { formatDateTime, linkifyLinks } from '@rh-support/utils';
23
21
  import DOMPurify from 'dompurify';
24
22
  import isEmpty from 'lodash/isEmpty';
25
23
  import isEqual from 'lodash/isEqual';
26
- import React, { useContext, useEffect, useRef, useState } from 'react';
27
- import { Trans, useTranslation } from 'react-i18next';
24
+ import React, { useContext, useEffect, useRef } from 'react';
25
+ import { Trans } from 'react-i18next';
26
+ // TODO: Re-enable after GraphQL migration of feedback
27
+ // import { useTranslation } from 'react-i18next';
28
28
  import { DiscussionType } from '../../../../reducers/CaseDiscussionTabReducer';
29
29
  import { PDFContext } from '../../PDFContainer';
30
30
  import { DiscussionItemLink } from './DiscussionItemLink';
@@ -33,55 +33,74 @@ const CaseComments = React.forwardRef((props, ref) => {
33
33
  var _a;
34
34
  const { caseNumber } = props;
35
35
  const markdownRef = useRef(null);
36
- const { t } = useTranslation();
36
+ // TODO: Re-enable `t` after GraphQL migration of feedback (Allowed Regression #5)
37
+ // const { t } = useTranslation();
37
38
  const ability = useContext(AbilityContext);
38
39
  const canSeePrivateComments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.VIEW_PRIVATE_COMMENT);
39
- const canSeeFeedbackButtons = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_FEEDBACK_BUTTONS) &&
40
- props.comment.isPublic &&
41
- props.comment.createdBy !== 'Automated Support Assistant';
42
- const [isFeedbackUpdating, setIsFeedbackUpdating] = useState(false);
40
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
41
+ // const canSeeFeedbackButtons =
42
+ // ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_FEEDBACK_BUTTONS) &&
43
+ // props.comment.isPublic &&
44
+ // props.comment.createdBy !== 'Automated Support Assistant';
45
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
46
+ // const [isFeedbackUpdating, setIsFeedbackUpdating] = useState(false);
43
47
  const { isExportingPDF } = useContext(PDFContext);
44
48
  const commentReply = (comment) => () => {
45
49
  props.onReply(comment.commentBody, comment.createdBy, comment.isPublic);
46
50
  };
47
51
  const onJumpToComment = (commentId) => () => props.showJumpToComment && props.onJumpToComment && props.onJumpToComment(commentId);
48
- const applyCommentFeedback = (comment, feedback) => (e) => __awaiter(void 0, void 0, void 0, function* () {
49
- e.preventDefault();
50
- if (props.feedback === feedback) {
51
- return;
52
- }
53
- const commJson = {
54
- feedback,
55
- accountNumber: props.accountNumber,
56
- commentId: comment.id,
57
- commentCreatedBy: comment.createdBy,
58
- };
59
- try {
60
- setIsFeedbackUpdating(true);
61
- if (props.feedback !== undefined) {
62
- yield publicApi.commentFeedback.updateCommentFeedback(caseNumber, commJson);
63
- }
64
- else {
65
- yield publicApi.commentFeedback.createCommentFeedback(caseNumber, commJson);
66
- }
67
- setIsFeedbackUpdating(false);
68
- // update state
69
- props.onFeedBackUpdate(comment.id, feedback);
70
- ToastNotification.addSuccessMessage(t(`Comment feedback has been successfully updated`));
71
- }
72
- catch (e) {
73
- setIsFeedbackUpdating(false);
74
- ToastNotification.addDangerMessage(t(`Comment feedback failed to update`));
75
- }
76
- });
77
- const commentFeedbackButtons = (comment, feedback) => (React.createElement("span", { className: "comment-feedback-buttons" },
78
- React.createElement(LoadingIndicator, { isInline: true, show: isFeedbackUpdating }),
79
- React.createElement(Tooltip, { position: TooltipPosition.top, content: t('Positive feedback') },
80
- React.createElement("button", { className: "btn btn-app btn-link", onClick: applyCommentFeedback(comment, 1), "data-tracking-id": "case-comment-feedback-up", type: "button" }, feedback === 1 ? (React.createElement(SmileIcon, { title: t('Remove positive feedback') })) : (React.createElement(OutlinedSmileIcon, { title: t('Leave positive feedback') })))),
81
- React.createElement(Tooltip, { position: TooltipPosition.top, content: t('Neutral feedback') },
82
- React.createElement("button", { className: "btn btn-app btn-link", onClick: applyCommentFeedback(comment, 0), "data-tracking-id": "case-comment-feedback-neutral", type: "button" }, feedback === 0 ? (React.createElement(MehIcon, { title: t('Remove neutral feedback') })) : (React.createElement(OutlinedMehIcon, { title: t('Leave neutral feedback') })))),
83
- React.createElement(Tooltip, { position: TooltipPosition.top, content: t('Negative feedback') },
84
- React.createElement("button", { className: "btn btn-app btn-link", onClick: applyCommentFeedback(comment, -1), "data-tracking-id": "case-comment-feedback-down", type: "button" }, feedback === -1 ? (React.createElement(FrownIcon, { title: t('Remove negative feedback'), "aria-label": t('Remove negative feedback') })) : (React.createElement(OutlinedFrownIcon, { title: t('Leave negative feedback'), "aria-label": t('Leave negative feedback') }))))));
52
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
53
+ // const applyCommentFeedback = (comment: ICaseComment, feedback) => async (e) => {
54
+ // e.preventDefault();
55
+ // if (props.feedback === feedback) return;
56
+ // const commJson: ICommentFeedback = {
57
+ // feedback,
58
+ // accountNumber: props.accountNumber,
59
+ // commentId: comment.id,
60
+ // commentCreatedBy: comment.createdBy,
61
+ // };
62
+ // try {
63
+ // setIsFeedbackUpdating(true);
64
+ // if (props.feedback !== undefined) {
65
+ // await publicApi.commentFeedback.updateCommentFeedback(caseNumber, commJson);
66
+ // } else {
67
+ // await publicApi.commentFeedback.createCommentFeedback(caseNumber, commJson);
68
+ // }
69
+ // setIsFeedbackUpdating(false);
70
+ // props.onFeedBackUpdate(comment.id, feedback);
71
+ // ToastNotification.addSuccessMessage(t(`Comment feedback has been successfully updated`));
72
+ // } catch (e) {
73
+ // setIsFeedbackUpdating(false);
74
+ // ToastNotification.addDangerMessage(t(`Comment feedback failed to update`));
75
+ // }
76
+ // };
77
+ // TODO: Re-enable after GraphQL migration of feedback (Allowed Regression #5)
78
+ // const commentFeedbackButtons = (comment: ICaseComment, feedback: number) => (
79
+ // <span className="comment-feedback-buttons">
80
+ // <LoadingIndicator isInline={true} show={isFeedbackUpdating} />
81
+ // <Tooltip position={TooltipPosition.top} content={t('Positive feedback')}>
82
+ // <button className="btn btn-app btn-link" onClick={applyCommentFeedback(comment, 1)}
83
+ // data-tracking-id="case-comment-feedback-up" type="button">
84
+ // {feedback === 1 ? <SmileIcon title={t('Remove positive feedback')} />
85
+ // : <OutlinedSmileIcon title={t('Leave positive feedback')} />}
86
+ // </button>
87
+ // </Tooltip>
88
+ // <Tooltip position={TooltipPosition.top} content={t('Neutral feedback')}>
89
+ // <button className="btn btn-app btn-link" onClick={applyCommentFeedback(comment, 0)}
90
+ // data-tracking-id="case-comment-feedback-neutral" type="button">
91
+ // {feedback === 0 ? <MehIcon title={t('Remove neutral feedback')} />
92
+ // : <OutlinedMehIcon title={t('Leave neutral feedback')} />}
93
+ // </button>
94
+ // </Tooltip>
95
+ // <Tooltip position={TooltipPosition.top} content={t('Negative feedback')}>
96
+ // <button className="btn btn-app btn-link" onClick={applyCommentFeedback(comment, -1)}
97
+ // data-tracking-id="case-comment-feedback-down" type="button">
98
+ // {feedback === -1 ? <FrownIcon title={t('Remove negative feedback')} aria-label={t('Remove negative feedback')} />
99
+ // : <OutlinedFrownIcon title={t('Leave negative feedback')} aria-label={t('Leave negative feedback')} />}
100
+ // </button>
101
+ // </Tooltip>
102
+ // </span>
103
+ // );
85
104
  const computeDiscussionCardCalss = (comment) => {
86
105
  if (comment.createdByType === 'Associate' && comment.createdBy === 'Automated Support Assistant') {
87
106
  return 'comment-automated';
@@ -134,8 +153,19 @@ const CaseComments = React.forwardRef((props, ref) => {
134
153
  return React.createElement(Trans, null, "Automated comment");
135
154
  }
136
155
  };
156
+ const sanitizeHtml = (html) => {
157
+ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
158
+ if (node.tagName === 'A') {
159
+ node.setAttribute('target', '_blank');
160
+ node.setAttribute('rel', 'noopener noreferrer');
161
+ }
162
+ });
163
+ const clean = DOMPurify.sanitize(html, { ADD_ATTR: ['target', 'rel'] });
164
+ DOMPurify.removeHook('afterSanitizeAttributes');
165
+ return clean;
166
+ };
137
167
  const commentText = (text) => {
138
- return { __html: DOMPurify.sanitize(text) };
168
+ return { __html: sanitizeHtml(text) };
139
169
  };
140
170
  // Transforms <strong> and <em> tags in HTML string to styled <span> tags to fix incorrect bold/italic rendering in exported PDF
141
171
  function formatMarkdownHtmlForPDF(htmlString) {
@@ -152,13 +182,13 @@ const CaseComments = React.forwardRef((props, ref) => {
152
182
  .replace(/<\/?ul>/gi, ''));
153
183
  }
154
184
  const commentMarkdown = (markdown) => {
155
- let htmlString = parseCommentMarkdown(markdown, { showButtonForAttachmentLink: true, disableImagePreview: isExportingPDF },
185
+ let htmlString = parseCommentMarkdown(markdown, { showButtonForAttachmentLink: true, disableImagePreview: isExportingPDF, encodeHTMLEntities: false },
156
186
  // @ts-ignore
157
187
  { openLinksInNewTab: true, gfm: true, breaks: true });
158
188
  if (isExportingPDF) {
159
189
  htmlString = formatMarkdownHtmlForPDF(htmlString);
160
190
  }
161
- return { __html: DOMPurify.sanitize(htmlString) };
191
+ return { __html: sanitizeHtml(htmlString) };
162
192
  };
163
193
  const onCommentAreaClick = (e) => {
164
194
  let { event } = e.target['dataset'];
@@ -176,10 +206,13 @@ const CaseComments = React.forwardRef((props, ref) => {
176
206
  const parseCommentHtml = (commentText, contentType) => {
177
207
  let text = commentText;
178
208
  if (contentType === EditorMode.PLAIN) {
179
- text = HTMLEntityChecker(commentText);
180
- // fix issue something like this <h1>ajhdjaj<d</h1>
181
- text = htmlEntitiesEncode(text);
182
- text = encodeAngularBrackets(text);
209
+ // Normalize SFDC HTML line breaks to newlines before encoding
210
+ text = text
211
+ .replace(/<br\s*\/?>/gi, '\n')
212
+ .replace(/<\/p>/gi, '\n')
213
+ .replace(/<p>/gi, '');
214
+ // Escape all angle brackets so plaintext tags don't get swallowed by DOMPurify
215
+ text = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
183
216
  text = linkifyLinks(text);
184
217
  text = linkifyWithCaseIDs(text);
185
218
  text = linkifyBZIDs(text);
@@ -187,17 +220,6 @@ const CaseComments = React.forwardRef((props, ref) => {
187
220
  }
188
221
  return text;
189
222
  };
190
- /* Purpose of this method is to break the default HTML Entity rendering on the UI when in plaintext mode.
191
- This is achieved by directly swapping the '&' in any html entity to `&amp` in e.g. &euro swaps to &ampeuro
192
- so it is rendered -> &euro on the UI instead of '€' */
193
- //PCM-10968
194
- const HTMLEntityChecker = (comment) => {
195
- if (comment.includes('&')) {
196
- return comment.replace(/&/g, '&amp;');
197
- }
198
- else
199
- return comment;
200
- };
201
223
  const computeCommentText = (comment) => {
202
224
  const parseComment = parseCommentHtml(comment.commentBody, comment.contentType);
203
225
  if (!isEmpty(comment.commentBody) && comment.contentType === EditorMode.MARKDOWN) {
@@ -237,7 +259,6 @@ const CaseComments = React.forwardRef((props, ref) => {
237
259
  React.createElement("div", { className: "comment-body", onClick: onCommentAreaClick, ref: markdownRef }, computeCommentText(props.comment)),
238
260
  React.createElement("footer", null,
239
261
  React.createElement("span", { className: "comment-note" }, computeCommentFooter(props.comment)),
240
- canSeeFeedbackButtons && commentFeedbackButtons(props.comment, props.feedback),
241
262
  React.createElement("span", { className: "pull-right pf-v6-l-flex pf-m-align-items-center" },
242
263
  props.showJumpToComment && (React.createElement(DiscussionItemLink, { onClick: onJumpToComment(props.comment.id), discussionType: DiscussionType.COMMENT, itemId: props.comment.id, caseNumber: caseNumber, isCopyLink: false },
243
264
  React.createElement(Trans, null, "Jump to comment"))),
@@ -1 +1 @@
1
- {"version":3,"file":"CommentSearch.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CommentSearch.tsx"],"names":[],"mappings":"AASA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,EAAkB,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAE5F,UAAU,MAAM;IACZ,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,sBAAsB,EAAE,OAAO,CAAC;CACnC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,qBAqG1C"}
1
+ {"version":3,"file":"CommentSearch.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CommentSearch.tsx"],"names":[],"mappings":"AASA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,EAAkB,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAE5F,UAAU,MAAM;IACZ,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,sBAAsB,EAAE,OAAO,CAAC;CACnC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,qBAsG1C"}
@@ -82,8 +82,9 @@ export function CommentSearch(props) {
82
82
  props.isCommentSearchCleared && !isEmpty(searchValue) && setSearchValue('');
83
83
  return (React.createElement("form", { onSubmit: handleSubmit },
84
84
  React.createElement("div", { className: "case-comment-input-container", "data-tracking-id": "case-comment-search" },
85
- React.createElement(TextInput, { type: "search", value: searchValue, className: "pf-v6-u-mr-lg", placeholder: t('Search for a comment'), id: "case-comment-search", "aria-label": t('Search for a comment'), onChange: (_event, value) => onSearchValChange(value), "data-tracking-id": "case-comment-search-input" }),
86
- searchValue && (React.createElement(Button, { icon: React.createElement(TimesIcon, null), onClick: clearSearchVal, className: "clear-btn", variant: "plain", "data-tracking-id": "case-comment-search-clear-button", "aria-label": t('Clear this search') })),
85
+ React.createElement("div", { className: "case-comment-search-input-wrapper" },
86
+ React.createElement(TextInput, { type: "search", value: searchValue, placeholder: t('Search for a comment'), id: "case-comment-search", "aria-label": t('Search for a comment'), onChange: (_event, value) => onSearchValChange(value), "data-tracking-id": "case-comment-search-input" }),
87
+ searchValue && (React.createElement(Button, { icon: React.createElement(TimesIcon, null), onClick: clearSearchVal, className: "clear-btn", variant: "plain", "data-tracking-id": "case-comment-search-clear-button", "aria-label": t('Clear this search') }))),
87
88
  React.createElement(Button, { variant: "secondary", type: "submit", "data-tracking-id": "case-comment-search-button" },
88
89
  React.createElement(Trans, null, "Search")))));
89
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DiscussionItemLink.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/DiscussionItemLink.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E,UAAU,MAAM;IACZ,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAClB;AAUD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,qBA0B/C"}
1
+ {"version":3,"file":"DiscussionItemLink.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/DiscussionItemLink.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E,UAAU,MAAM;IACZ,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAClB;AAUD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,qBAiC/C"}
@@ -19,8 +19,14 @@ export function DiscussionItemLink(props) {
19
19
  };
20
20
  return getStringifiedParams(Object.assign(Object.assign({}, requiredQueries), newQueryObj));
21
21
  };
22
+ const handleClick = (e) => {
23
+ if (props.isCopyLink) {
24
+ e.preventDefault();
25
+ }
26
+ props.onClick();
27
+ };
22
28
  return (React.createElement(Link, { replace: true, to: {
23
29
  pathname: `/case/${props.caseNumber}/discussion`,
24
30
  search: getQueryString(),
25
- }, className: "case-public-private-link", onClick: props.onClick, "data-tracking-id": `${!props.isCopyLink ? 'jumptocomment-' : 'case-'}${trackingIdMap[props.discussionType]}` }, props.children));
31
+ }, className: "case-public-private-link", onClick: handleClick, "data-tracking-id": `${!props.isCopyLink ? 'jumptocomment-' : 'case-'}${trackingIdMap[props.discussionType]}` }, props.children));
26
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"JumpAndCopyLink.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/JumpAndCopyLink.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAG/E,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,cAAc,CAAC;CAClC;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,qBA8BrC;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"JumpAndCopyLink.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/JumpAndCopyLink.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAG/E,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,cAAc,CAAC;CAClC;AAQD,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,qBA+BrC;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -4,13 +4,20 @@ import { useCopyToClipboard } from '@rh-support/components';
4
4
  import React, { useRef } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { DiscussionItemLink } from './DiscussionItemLink';
7
+ function getAppBasePath() {
8
+ const path = window.location.pathname;
9
+ if (path.startsWith('/support-beta'))
10
+ return '/support-beta';
11
+ return '/support/cases';
12
+ }
7
13
  function JumpAndCopyLink(props) {
8
14
  const { t } = useTranslation();
9
15
  const clipboardRefLink = useRef(null);
10
16
  const queryString = `${props.discussionType}Id=${props.cardId}`;
17
+ const basePath = getAppBasePath();
11
18
  const { clipboardText, copyToClipboard } = useCopyToClipboard(clipboardRefLink);
12
19
  return (React.createElement(React.Fragment, null,
13
- React.createElement("div", { ref: clipboardRefLink, style: { position: 'absolute', left: '-9999px' } }, `https://${window.location.host}/support/cases/#/case/${props.caseNumber}/discussion?${queryString}`),
20
+ React.createElement("div", { ref: clipboardRefLink, style: { position: 'absolute', left: '-9999px' } }, `https://${window.location.host}${basePath}/#/case/${props.caseNumber}/discussion?${queryString}`),
14
21
  React.createElement(DiscussionItemLink, { onClick: copyToClipboard, caseNumber: props.caseNumber, discussionType: props.discussionType, itemId: props.cardId, isCopyLink: true },
15
22
  React.createElement(Popover, { position: PopoverPosition.top, bodyContent: (hide) => React.createElement("div", null, clipboardText), hasAutoWidth: true, showClose: false },
16
23
  React.createElement(LinkIcon, { title: t('Copy link') })))));
@@ -1,15 +1,20 @@
1
1
  import { Dispatch, MutableRefObject } from 'react';
2
2
  interface UseAttachmentUploadCompletionParams {
3
3
  isUploadingAttachments: boolean;
4
- hasSomeUnUploadedFiles: boolean;
4
+ hasQueuedUploads: boolean;
5
+ hasAbortedOrFailed: boolean;
5
6
  isUploadingAttachmentPrevious: MutableRefObject<boolean>;
6
7
  caseDispatch: Dispatch<any>;
7
8
  isInternal: boolean;
8
9
  status: string | undefined;
9
10
  resetAttachmentSection: () => void;
10
- onAttachmentAdded: () => void;
11
11
  setCssCommentAgreed: (v: boolean) => void;
12
12
  }
13
- export declare function useAttachmentUploadCompletion({ isUploadingAttachments, hasSomeUnUploadedFiles, isUploadingAttachmentPrevious, caseDispatch, isInternal, status, resetAttachmentSection, onAttachmentAdded, setCssCommentAgreed, }: UseAttachmentUploadCompletionParams): void;
13
+ /**
14
+ * Batch cleanup after uploads settle.
15
+ * Per-file success already refreshes discussion and dismisses completed rows;
16
+ * this resets the panel when nothing aborted/failed remains.
17
+ */
18
+ export declare function useAttachmentUploadCompletion({ isUploadingAttachments, hasQueuedUploads, hasAbortedOrFailed, isUploadingAttachmentPrevious, caseDispatch, isInternal, status, resetAttachmentSection, setCssCommentAgreed, }: UseAttachmentUploadCompletionParams): void;
14
19
  export {};
15
20
  //# sourceMappingURL=useAttachmentUploadCompletion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAttachmentUploadCompletion.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAa,MAAM,OAAO,CAAC;AAK9D,UAAU,mCAAmC;IACzC,sBAAsB,EAAE,OAAO,CAAC;IAChC,sBAAsB,EAAE,OAAO,CAAC;IAChC,6BAA6B,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzD,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,sBAAsB,EAAE,MAAM,IAAI,CAAC;IACnC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7C;AAED,wBAAgB,6BAA6B,CAAC,EAC1C,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,YAAY,EACZ,UAAU,EACV,MAAM,EACN,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,GACtB,EAAE,mCAAmC,QAiBrC"}
1
+ {"version":3,"file":"useAttachmentUploadCompletion.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment/useAttachmentUploadCompletion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAa,MAAM,OAAO,CAAC;AAI9D,UAAU,mCAAmC;IACzC,sBAAsB,EAAE,OAAO,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,6BAA6B,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzD,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,sBAAsB,EAAE,MAAM,IAAI,CAAC;IACnC,mBAAmB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,EAC1C,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,6BAA6B,EAC7B,YAAY,EACZ,UAAU,EACV,MAAM,EACN,sBAAsB,EACtB,mBAAmB,GACtB,EAAE,mCAAmC,QAerC"}
@@ -1,19 +1,21 @@
1
- import { ToastNotification } from '@rh-support/components';
2
1
  import { useEffect } from 'react';
3
- import { useTranslation } from 'react-i18next';
4
2
  import { checkForCaseStatusToggleOnAttachOrComment } from '../../../../../reducers/CaseReducer';
5
- export function useAttachmentUploadCompletion({ isUploadingAttachments, hasSomeUnUploadedFiles, isUploadingAttachmentPrevious, caseDispatch, isInternal, status, resetAttachmentSection, onAttachmentAdded, setCssCommentAgreed, }) {
6
- const { t } = useTranslation();
3
+ /**
4
+ * Batch cleanup after uploads settle.
5
+ * Per-file success already refreshes discussion and dismisses completed rows;
6
+ * this resets the panel when nothing aborted/failed remains.
7
+ */
8
+ export function useAttachmentUploadCompletion({ isUploadingAttachments, hasQueuedUploads, hasAbortedOrFailed, isUploadingAttachmentPrevious, caseDispatch, isInternal, status, resetAttachmentSection, setCssCommentAgreed, }) {
7
9
  useEffect(() => {
8
- const justFinished = isUploadingAttachmentPrevious.current && !isUploadingAttachments && !hasSomeUnUploadedFiles;
10
+ const justFinished = isUploadingAttachmentPrevious.current && !isUploadingAttachments && !hasQueuedUploads;
9
11
  if (justFinished) {
10
- ToastNotification.addSuccessMessage(t('Attachment(s) uploaded successfully'));
12
+ if (!hasAbortedOrFailed) {
13
+ resetAttachmentSection();
14
+ }
11
15
  checkForCaseStatusToggleOnAttachOrComment(caseDispatch, isInternal, status);
12
- resetAttachmentSection();
13
- onAttachmentAdded();
14
16
  setCssCommentAgreed(false);
15
17
  }
16
18
  isUploadingAttachmentPrevious.current = isUploadingAttachments;
17
19
  // eslint-disable-next-line react-hooks/exhaustive-deps
18
- }, [isUploadingAttachments]);
20
+ }, [isUploadingAttachments, hasQueuedUploads, hasAbortedOrFailed]);
19
21
  }
@@ -1 +1 @@
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,qBA2axC"}
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;AAMpF,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAmB5E,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,qBAucxC"}