@rh-support/troubleshoot 2.7.11 → 2.7.13
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.
- package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Case.js +5 -10
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/AsaCommentFeedbackModal.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/AsaCommentFeedbackModal.js +4 -15
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.d.ts +3 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.js +117 -110
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.js +50 -52
- package/lib/esm/css/case.css +12 -4
- package/lib/esm/hooks/useCaseComments/useCaseComments.d.ts.map +1 -1
- package/lib/esm/hooks/useCaseComments/useCaseComments.js +1 -13
- package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts +4 -1
- package/lib/esm/reducers/CaseDiscussionTabReducer.d.ts.map +1 -1
- package/lib/esm/reducers/CaseDiscussionTabReducer.js +11 -2
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAoBA,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,
|
|
1
|
+
{"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAoBA,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+QzC"}
|
|
@@ -20,10 +20,9 @@ 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 { fetchAttachments, fetchCaseEscalations,
|
|
23
|
+
import { fetchAttachments, fetchCaseEscalations,
|
|
24
24
|
// fetchExternalTrackers,
|
|
25
|
-
|
|
26
|
-
} from '../../reducers/CaseDetailsPageReducer';
|
|
25
|
+
fetchFeedbacks, } from '../../reducers/CaseDetailsPageReducer';
|
|
27
26
|
import { setCaseAccountNumber } from '../../reducers/CaseReducer';
|
|
28
27
|
import { ArchivedCaseBanner } from './ArchivedCaseBanner';
|
|
29
28
|
import { CaseDetailsAside } from './CaseDetailsAside';
|
|
@@ -140,13 +139,9 @@ export default function Case(props) {
|
|
|
140
139
|
// targetCaseNumber
|
|
141
140
|
// );
|
|
142
141
|
// }
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// (action) => currentCaseRef.current === targetCaseNumber && caseDetailsPageDispatch(action),
|
|
147
|
-
// targetCaseNumber
|
|
148
|
-
// );
|
|
149
|
-
// }
|
|
142
|
+
if (canSeeFeedbackButtons) {
|
|
143
|
+
fetchFeedbacks((action) => currentCaseRef.current === targetCaseNumber && caseDetailsPageDispatch(action), targetCaseNumber);
|
|
144
|
+
}
|
|
150
145
|
if (currentCaseRef.current === targetCaseNumber) {
|
|
151
146
|
checkRemoteSessionFlag();
|
|
152
147
|
}
|
package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/AsaCommentFeedbackModal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsaCommentFeedbackModal.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/AsaCommentFeedbackModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AsaCommentFeedbackModal.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/AsaCommentFeedbackModal.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;EAIvB,CAAC;AAEX,UAAU,MAAM;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;CACpG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,qBA+JpD"}
|
|
@@ -7,7 +7,7 @@ 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 { Button, Form, FormGroup,
|
|
10
|
+
import { Button, Form, FormGroup, Icon, Modal, ModalBody, ModalFooter, ModalHeader, ModalVariant, TextArea, } from '@patternfly/react-core';
|
|
11
11
|
import OutlinedFrownIcon from '@patternfly/react-icons/dist/js/icons/outlined-frown-icon';
|
|
12
12
|
import OutlinedMehIcon from '@patternfly/react-icons/dist/js/icons/outlined-meh-icon';
|
|
13
13
|
import OutlinedSmileIcon from '@patternfly/react-icons/dist/js/icons/outlined-smile-icon';
|
|
@@ -25,12 +25,10 @@ export function AsaCommentFeedbackModal(props) {
|
|
|
25
25
|
const [selectedFeedback, setSelectedFeedback] = useState(props.initialFeedback);
|
|
26
26
|
const [feedbackReason, setFeedbackReason] = useState((_a = props.initialFeedbackReason) !== null && _a !== void 0 ? _a : '');
|
|
27
27
|
const [showRatingError, setShowRatingError] = useState(false);
|
|
28
|
-
const [showFeedbackTextError, setShowFeedbackTextError] = useState(false);
|
|
29
28
|
const trimmedFeedbackReason = feedbackReason.trim();
|
|
30
29
|
const savedFeedbackReason = (_b = props.initialFeedbackReason) !== null && _b !== void 0 ? _b : '';
|
|
31
30
|
const hasChanges = selectedFeedback !== props.initialFeedback || feedbackReason !== savedFeedbackReason;
|
|
32
|
-
const
|
|
33
|
-
const isSubmitDisabled = props.isSubmitting || hasValidationError;
|
|
31
|
+
const isSubmitDisabled = props.isSubmitting || showRatingError;
|
|
34
32
|
useEffect(() => {
|
|
35
33
|
var _a;
|
|
36
34
|
if (props.isOpen) {
|
|
@@ -38,7 +36,6 @@ export function AsaCommentFeedbackModal(props) {
|
|
|
38
36
|
setFeedbackReason((_a = props.initialFeedbackReason) !== null && _a !== void 0 ? _a : '');
|
|
39
37
|
}
|
|
40
38
|
setShowRatingError(false);
|
|
41
|
-
setShowFeedbackTextError(false);
|
|
42
39
|
}, [props.isOpen, props.initialFeedback, props.initialFeedbackReason]);
|
|
43
40
|
const handleClose = () => {
|
|
44
41
|
if (props.isSubmitting) {
|
|
@@ -52,10 +49,6 @@ export function AsaCommentFeedbackModal(props) {
|
|
|
52
49
|
setShowRatingError(true);
|
|
53
50
|
return;
|
|
54
51
|
}
|
|
55
|
-
if (trimmedFeedbackReason.length === 0) {
|
|
56
|
-
setShowFeedbackTextError(true);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
52
|
if (!hasChanges) {
|
|
60
53
|
return;
|
|
61
54
|
}
|
|
@@ -84,12 +77,8 @@ export function AsaCommentFeedbackModal(props) {
|
|
|
84
77
|
})),
|
|
85
78
|
showRatingError && selectedFeedback === undefined && (React.createElement("p", { className: "form-instructions form-invalid pf-v6-u-mt-sm" },
|
|
86
79
|
React.createElement(Trans, null, "Please select a value")))),
|
|
87
|
-
React.createElement(FormGroup, { label: t('How can we improve?'),
|
|
88
|
-
|
|
89
|
-
React.createElement(HelperText, null,
|
|
90
|
-
React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Please enter your feedback'))))),
|
|
91
|
-
React.createElement(TextArea, { id: "asa-comment-feedback-reason", name: "feedbackReason", value: feedbackReason, validated: showFeedbackTextError ? ValidatedOptions.error : ValidatedOptions.default, onChange: (_event, value) => {
|
|
92
|
-
setShowFeedbackTextError(false);
|
|
80
|
+
React.createElement(FormGroup, { label: t('How can we improve?'), fieldId: "asa-comment-feedback-reason" },
|
|
81
|
+
React.createElement(TextArea, { id: "asa-comment-feedback-reason", name: "feedbackReason", value: feedbackReason, onChange: (_event, value) => {
|
|
93
82
|
setFeedbackReason(value);
|
|
94
83
|
}, placeholder: t('Describe your suggestion in details'), "aria-label": t('How can we improve?'), isDisabled: props.isSubmitting, resizeOrientation: "vertical" })),
|
|
95
84
|
React.createElement("p", { className: "asa-feedback-privacy" },
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ICaseComment } from '@cee-eng/hydrajs/@types/api/public/case';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
export declare const AUTOMATED_SUPPORT_ASSISTANT = "Support AI Assistant Service Account";
|
|
3
4
|
interface IProps {
|
|
4
5
|
caseNumber: string;
|
|
5
6
|
comment: ICaseComment;
|
|
6
7
|
feedback: number;
|
|
7
|
-
|
|
8
|
+
feedbackReason?: string;
|
|
9
|
+
onFeedBackUpdate: (id: string, feedback: number, feedbackReason?: string) => void;
|
|
8
10
|
accountNumber: string;
|
|
9
11
|
onReply: (author: string, commentId: string, timestamp: string) => void;
|
|
10
12
|
showJumpToComment?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseComments.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.tsx"],"names":[],"mappings":"
|
|
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;AAuBvE,OAAO,KAAkD,MAAM,OAAO,CAAC;AAUvE,eAAO,MAAM,2BAA2B,yCAAyC,CAAC;AAElF,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClF,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,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,4EAkdhB,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -1,105 +1,120 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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';
|
|
3
11
|
import { EventTypes, linkifyBZIDs, linkifyWithCaseIDs, processRME } from '@cee-eng/ui-toolkit';
|
|
4
|
-
import { Icon } from '@patternfly/react-core';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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';
|
|
12
|
+
import { Alert, Button, ButtonVariant, 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';
|
|
13
19
|
import UserCircleIcon from '@patternfly/react-icons/dist/js/icons/user-circle-icon';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import { AbilityContext,
|
|
17
|
-
// CaseDetailsFields, // TODO: Re-enable after GraphQL migration of feedback
|
|
18
|
-
CaseDiscussionFields, resourceActions, resources, } from '@rh-support/user-permissions';
|
|
20
|
+
import { LoadingIndicator, ToastNotification } from '@rh-support/components';
|
|
21
|
+
import { AbilityContext, CaseDetailsFields, CaseDiscussionFields, resourceActions, resources, } from '@rh-support/user-permissions';
|
|
19
22
|
import { formatDateTime, linkifyLinks } from '@rh-support/utils';
|
|
20
23
|
import DOMPurify from 'dompurify';
|
|
21
24
|
import isEmpty from 'lodash/isEmpty';
|
|
22
25
|
import isEqual from 'lodash/isEqual';
|
|
23
|
-
import React, { useContext, useEffect, useRef } from 'react';
|
|
24
|
-
import { Trans } from 'react-i18next';
|
|
25
|
-
// TODO: Re-enable after GraphQL migration of feedback
|
|
26
|
-
// import { useTranslation } from 'react-i18next';
|
|
26
|
+
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
27
|
+
import { Trans, useTranslation } from 'react-i18next';
|
|
27
28
|
import { DiscussionType } from '../../../../reducers/CaseDiscussionTabReducer';
|
|
28
29
|
import { linkifyHtmlTextNodes } from '../../../../utils/linkifyHtmlTextNodes';
|
|
29
30
|
import { PDFContext } from '../../PDFContainer';
|
|
31
|
+
import { AsaCommentFeedbackModal } from './AsaCommentFeedbackModal';
|
|
30
32
|
import { DiscussionItemLink } from './DiscussionItemLink';
|
|
31
33
|
import { JumpAndCopyLink } from './JumpAndCopyLink';
|
|
34
|
+
export const AUTOMATED_SUPPORT_ASSISTANT = 'Support AI Assistant Service Account';
|
|
32
35
|
const CaseComments = React.forwardRef((props, ref) => {
|
|
33
|
-
var _a;
|
|
36
|
+
var _a, _b;
|
|
34
37
|
const { caseNumber } = props;
|
|
35
38
|
const markdownRef = useRef(null);
|
|
36
|
-
|
|
37
|
-
// const { t } = useTranslation();
|
|
39
|
+
const { t } = useTranslation();
|
|
38
40
|
const ability = useContext(AbilityContext);
|
|
39
41
|
const canSeePrivateComments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.VIEW_PRIVATE_COMMENT);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
const isAsaComment = props.comment.createdBy === AUTOMATED_SUPPORT_ASSISTANT;
|
|
43
|
+
const canGiveCommentFeedback = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_FEEDBACK_BUTTONS);
|
|
44
|
+
const canSeeFeedbackButtons = canGiveCommentFeedback && props.comment.isPublic && !isAsaComment;
|
|
45
|
+
const [isFeedbackUpdating, setIsFeedbackUpdating] = useState(false);
|
|
46
|
+
const [isAsaFeedbackModalOpen, setIsAsaFeedbackModalOpen] = useState(false);
|
|
47
|
+
const [savedFeedbackValue, setSavedFeedbackValue] = useState(props.feedback);
|
|
48
|
+
const [savedFeedbackReason, setSavedFeedbackReason] = useState((_a = props.feedbackReason) !== null && _a !== void 0 ? _a : '');
|
|
47
49
|
const { isExportingPDF } = useContext(PDFContext);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
setSavedFeedbackValue(props.feedback);
|
|
52
|
+
}, [props.feedback]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
var _a;
|
|
55
|
+
setSavedFeedbackReason((_a = props.feedbackReason) !== null && _a !== void 0 ? _a : '');
|
|
56
|
+
}, [props.feedbackReason]);
|
|
48
57
|
const onJumpToComment = (commentId) => () => props.showJumpToComment && props.onJumpToComment && props.onJumpToComment(commentId);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
58
|
+
const applyCommentFeedback = (comment, feedback) => (e) => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
+
e.preventDefault();
|
|
60
|
+
if (props.feedback === feedback) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
yield submitCommentFeedback(comment, feedback);
|
|
64
|
+
});
|
|
65
|
+
const submitCommentFeedback = (comment, feedback, feedbackReason) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
var _a;
|
|
67
|
+
const commJson = Object.assign({ feedback, accountNumber: props.accountNumber, commentId: comment.id, commentCreatedBy: comment.createdBy }, (feedbackReason !== undefined ? { feedbackReason } : {}));
|
|
68
|
+
try {
|
|
69
|
+
setIsFeedbackUpdating(true);
|
|
70
|
+
const hasExistingFeedback = savedFeedbackValue !== undefined;
|
|
71
|
+
const response = hasExistingFeedback
|
|
72
|
+
? yield publicApi.commentFeedback.updateCommentFeedback(caseNumber, commJson)
|
|
73
|
+
: yield publicApi.commentFeedback.createCommentFeedback(caseNumber, commJson);
|
|
74
|
+
setIsFeedbackUpdating(false);
|
|
75
|
+
const responseFeedback = (response === null || response === void 0 ? void 0 : response.feedback) !== undefined && (response === null || response === void 0 ? void 0 : response.feedback) !== null && `${response.feedback}` !== ''
|
|
76
|
+
? parseInt(String(response.feedback), 10)
|
|
77
|
+
: feedback;
|
|
78
|
+
const savedFeedback = Number.isNaN(responseFeedback) ? feedback : responseFeedback;
|
|
79
|
+
const savedReason = (_a = response === null || response === void 0 ? void 0 : response.feedbackReason) !== null && _a !== void 0 ? _a : feedbackReason;
|
|
80
|
+
setSavedFeedbackValue(savedFeedback);
|
|
81
|
+
if (feedbackReason !== undefined) {
|
|
82
|
+
setSavedFeedbackReason(savedReason !== null && savedReason !== void 0 ? savedReason : '');
|
|
83
|
+
props.onFeedBackUpdate(comment.id, savedFeedback, savedReason !== null && savedReason !== void 0 ? savedReason : '');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
props.onFeedBackUpdate(comment.id, savedFeedback);
|
|
87
|
+
}
|
|
88
|
+
ToastNotification.addSuccessMessage(t(`Comment feedback has been successfully updated`));
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
setIsFeedbackUpdating(false);
|
|
93
|
+
ToastNotification.addDangerMessage(t(`Comment feedback failed to update`));
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const openAsaFeedbackModal = (e) => {
|
|
98
|
+
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
99
|
+
setIsAsaFeedbackModalOpen(true);
|
|
100
|
+
};
|
|
101
|
+
const onSubmitAsaFeedback = (feedback, feedbackReason) => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
+
const didSubmit = yield submitCommentFeedback(props.comment, feedback, feedbackReason);
|
|
103
|
+
if (didSubmit) {
|
|
104
|
+
setIsAsaFeedbackModalOpen(false);
|
|
105
|
+
}
|
|
106
|
+
return didSubmit;
|
|
107
|
+
});
|
|
108
|
+
const commentFeedbackButtons = (comment, feedback) => (React.createElement("span", { className: "comment-feedback-buttons" },
|
|
109
|
+
React.createElement(LoadingIndicator, { isInline: true, show: isFeedbackUpdating }),
|
|
110
|
+
React.createElement(Tooltip, { position: TooltipPosition.top, content: t('Positive feedback') },
|
|
111
|
+
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') })))),
|
|
112
|
+
React.createElement(Tooltip, { position: TooltipPosition.top, content: t('Neutral feedback') },
|
|
113
|
+
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') })))),
|
|
114
|
+
React.createElement(Tooltip, { position: TooltipPosition.top, content: t('Negative feedback') },
|
|
115
|
+
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') }))))));
|
|
101
116
|
const computeDiscussionCardCalss = (comment) => {
|
|
102
|
-
if (comment.
|
|
117
|
+
if (comment.createdBy === AUTOMATED_SUPPORT_ASSISTANT) {
|
|
103
118
|
return 'comment-automated';
|
|
104
119
|
}
|
|
105
120
|
else if (comment.createdByType === 'Associate') {
|
|
@@ -124,8 +139,9 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
124
139
|
}
|
|
125
140
|
};
|
|
126
141
|
const computeCommentAuthorIcon = (comment) => {
|
|
127
|
-
if (comment.
|
|
128
|
-
return (React.createElement("
|
|
142
|
+
if (comment.createdBy === AUTOMATED_SUPPORT_ASSISTANT) {
|
|
143
|
+
return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", className: "asa-comment-author-icon", style: { display: 'block', flexShrink: 0, marginRight: '8px' } },
|
|
144
|
+
React.createElement("path", { d: "M6.12207 2.1875C6.35023 2.1875 6.55802 2.38112 6.57617 2.6084C6.78104 5.19193 8.80513 7.2158 11.3887 7.4209C11.6159 7.43885 11.8096 7.64685 11.8096 7.875C11.8096 8.10357 11.6159 8.31072 11.3887 8.3291C8.80515 8.53416 6.78181 10.5585 6.57715 13.1416C6.55879 13.3687 6.35032 13.5625 6.12207 13.5625C5.89427 13.5623 5.6871 13.3688 5.66895 13.1416C5.46407 10.5581 3.4399 8.53431 0.856445 8.3291C0.628957 8.31116 0.435567 8.10314 0.435547 7.875C0.435547 7.64565 0.630491 7.43726 0.859375 7.4209C3.43949 7.21584 5.46331 5.19153 5.66797 2.6084C5.68628 2.38137 5.89416 2.1877 6.12207 2.1875ZM6.12305 4.47754C5.50484 6.02837 4.27607 7.25674 2.72461 7.875C4.27677 8.49323 5.50406 9.72157 6.12207 11.2725C6.7403 9.72157 7.96918 8.49323 9.52051 7.875C7.96835 7.25677 6.74106 6.02843 6.12305 4.47754ZM10.9365 0.654297C11.0628 0.654455 11.1709 0.745742 11.1943 0.87207C11.373 1.84914 12.1499 2.62611 13.127 2.80469C13.2533 2.8283 13.3447 2.93617 13.3447 3.0625C13.3447 3.18886 13.2533 3.2967 13.127 3.32031C12.1498 3.4989 11.3729 4.27583 11.1943 5.25293C11.1709 5.3793 11.0628 5.47054 10.9365 5.4707C10.8101 5.4707 10.7012 5.37937 10.6777 5.25293C10.4996 4.27597 9.72346 3.49901 8.74609 3.32031C8.61962 3.29682 8.52736 3.18892 8.52734 3.0625C8.52734 2.93606 8.61961 2.82818 8.74609 2.80469C9.72344 2.626 10.4995 1.84901 10.6777 0.87207C10.7012 0.745589 10.8101 0.654297 10.9365 0.654297Z", fill: "#1F1F1F" })));
|
|
129
145
|
}
|
|
130
146
|
else if (comment.createdByType === 'Associate') {
|
|
131
147
|
return (React.createElement("img", { src: "https://static.redhat.com/libs/redhat/brand-assets/2/corp/logo--hat-only.svg", height: "18", width: "18", "aria-hidden": "true", alt: "Red Hat associate comment", title: "Red Hat associate", style: { verticalAlign: '-0.125em', marginRight: '6px' } }));
|
|
@@ -140,19 +156,13 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
140
156
|
}
|
|
141
157
|
};
|
|
142
158
|
const computeCommentFooter = (comment) => {
|
|
143
|
-
if (!props.comment.isPublic
|
|
144
|
-
return React.createElement(Trans, null, "Private automated comment");
|
|
145
|
-
}
|
|
146
|
-
else if (!props.comment.isPublic) {
|
|
159
|
+
if (!props.comment.isPublic) {
|
|
147
160
|
return React.createElement(Trans, null, "Private comment");
|
|
148
161
|
}
|
|
149
162
|
else if (comment.createdBy === 'Automated Support Assistant') {
|
|
150
163
|
return React.createElement(Trans, null, "Automated comment");
|
|
151
164
|
}
|
|
152
165
|
};
|
|
153
|
-
// Tags the Quill RTE legitimately produces — everything else was typed
|
|
154
|
-
// literally by the user or injected from an external source (SFDC) and
|
|
155
|
-
// should render as visible text, not interpreted as HTML formatting.
|
|
156
166
|
const QUILL_TAGS = new Set([
|
|
157
167
|
'p',
|
|
158
168
|
'br',
|
|
@@ -192,19 +202,13 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
192
202
|
const commentText = (text) => {
|
|
193
203
|
return { __html: sanitizeHtml(text) };
|
|
194
204
|
};
|
|
195
|
-
// Transforms <strong> and <em> tags in HTML string to styled <span> tags to fix incorrect bold/italic rendering in exported PDF
|
|
196
205
|
function formatMarkdownHtmlForPDF(htmlString) {
|
|
197
|
-
return
|
|
198
|
-
// Handle nested <strong><em>...</em></strong> or <em><strong>...</strong></em> and apply both bold and italic (skew) styles
|
|
206
|
+
return htmlString
|
|
199
207
|
.replace(/<(strong|em)>\s*<(em|strong)>(.*?)<\/\2>\s*<\/\1>/gi, '<span style="font-weight: bold; font-size: 0.95em; font-style: italic;">$3</span>')
|
|
200
|
-
// Handle standalone <strong>
|
|
201
208
|
.replace(/<strong>(.*?)<\/strong>/gi, '<span style="font-weight: bold; font-size: 0.95em; margin-right: -10px;">$1</span>')
|
|
202
|
-
// Handle standalone <em>
|
|
203
209
|
.replace(/<em>(.*?)<\/em>/gi, '<span style="font-style: italic;font-size: 0.95em; opacity: 0.70;margin-right: 7px;">$1</span>')
|
|
204
|
-
// Replace list items with dash bullets
|
|
205
210
|
.replace(/<li>(.*?)<\/li>/gi, '<div style="margin-left: 1.2em;">- $1</div>')
|
|
206
|
-
|
|
207
|
-
.replace(/<\/?ul>/gi, ''));
|
|
211
|
+
.replace(/<\/?ul>/gi, '');
|
|
208
212
|
}
|
|
209
213
|
const onCommentAreaClick = (e) => {
|
|
210
214
|
let { event } = e.target['dataset'];
|
|
@@ -222,7 +226,6 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
222
226
|
const parseCommentHtml = (commentText, contentType) => {
|
|
223
227
|
let text = commentText;
|
|
224
228
|
if (contentType === 'plaintext') {
|
|
225
|
-
// Legacy plain-text comments: normalize SFDC HTML line breaks
|
|
226
229
|
text = text
|
|
227
230
|
.replace(/<br\s*\/?>/gi, '\n')
|
|
228
231
|
.replace(/<\/p>/gi, '\n')
|
|
@@ -238,12 +241,10 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
238
241
|
const computeCommentText = (comment) => {
|
|
239
242
|
if (isEmpty(comment.commentBody))
|
|
240
243
|
return null;
|
|
241
|
-
// Legacy plain-text comments still need escaping and linkification
|
|
242
244
|
if (comment.contentType === 'plaintext') {
|
|
243
245
|
const parseComment = parseCommentHtml(comment.commentBody, comment.contentType);
|
|
244
246
|
return (React.createElement("pre", { className: "push-top-narrow comment-plaintext reset-pre-text", dangerouslySetInnerHTML: commentText(parseComment), style: { fontFamily: isExportingPDF ? 'DejaVu Sans' : '' } }));
|
|
245
247
|
}
|
|
246
|
-
// HTML comments (new rich text or legacy markdown — both stored as HTML)
|
|
247
248
|
let htmlString = comment.commentBody;
|
|
248
249
|
htmlString = linkifyHtmlTextNodes(htmlString);
|
|
249
250
|
if (isExportingPDF) {
|
|
@@ -261,28 +262,34 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
261
262
|
});
|
|
262
263
|
}
|
|
263
264
|
}, [props.comment, isExportingPDF]);
|
|
264
|
-
if (!((
|
|
265
|
+
if (!((_b = props.comment) === null || _b === void 0 ? void 0 : _b.isPublic) && !canSeePrivateComments)
|
|
265
266
|
return React.createElement(React.Fragment, null);
|
|
266
267
|
return (React.createElement("article", { ref: ref, id: props.comment.id, "aria-label": `Comment by ${props.comment.lastModifiedById}`, className: `prevent-split ${computePrivateComment(props.comment)} support-comment ${computeDiscussionCardCalss(props.comment)} ${ref ? 'selected-case-comment' : ''}` },
|
|
267
268
|
React.createElement("header", null,
|
|
268
269
|
React.createElement("h4", null,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
isAsaComment ? (React.createElement("span", { className: "asa-comment-author" },
|
|
271
|
+
computeCommentAuthorIcon(props.comment),
|
|
272
|
+
React.createElement("span", null, props.comment.createdBy))) : (React.createElement(React.Fragment, null,
|
|
273
|
+
computeCommentAuthorIcon(props.comment),
|
|
274
|
+
props.comment.createdBy)),
|
|
272
275
|
props.comment.createdByType === 'Partner' && (React.createElement("span", null,
|
|
273
276
|
' ',
|
|
274
277
|
"(",
|
|
275
278
|
React.createElement(Trans, null, "Partner"),
|
|
276
279
|
")"))),
|
|
277
280
|
React.createElement("time", null, formatDateTime(props.comment.lastModifiedDate))),
|
|
281
|
+
isAsaComment && (React.createElement(Alert, { className: `asa-comment-alert ${isExportingPDF ? 'hide-in-pdf' : ''}`, isInline: true, variant: "custom", title: t('Always review AI-Generated content prior to use') })),
|
|
278
282
|
React.createElement("div", { className: "comment-body", onClick: onCommentAreaClick, ref: markdownRef }, computeCommentText(props.comment)),
|
|
279
283
|
React.createElement("footer", null,
|
|
280
284
|
React.createElement("span", { className: "comment-note" }, computeCommentFooter(props.comment)),
|
|
285
|
+
canSeeFeedbackButtons && commentFeedbackButtons(props.comment, props.feedback),
|
|
281
286
|
React.createElement("span", { className: "pull-right pf-v6-l-flex pf-m-align-items-center" },
|
|
282
287
|
props.showJumpToComment && (React.createElement(DiscussionItemLink, { onClick: onJumpToComment(props.comment.id), discussionType: DiscussionType.COMMENT, itemId: props.comment.id, caseNumber: caseNumber, isCopyLink: false },
|
|
283
288
|
React.createElement(Trans, null, "Jump to comment"))),
|
|
284
|
-
React.createElement(
|
|
285
|
-
React.createElement(Trans, null, "
|
|
286
|
-
|
|
289
|
+
isAsaComment ? (React.createElement(Button, { variant: ButtonVariant.link, isInline: true, className: `asa-send-feedback-link ${isExportingPDF ? 'hide-in-pdf' : ''}`, onClick: openAsaFeedbackModal, "data-tracking-id": "case-asa-comment-send-feedback-footer" },
|
|
290
|
+
React.createElement(Trans, null, "Send feedback"))) : (React.createElement("button", { onClick: () => props.onReply(props.comment.lastModifiedById, props.comment.id, props.comment.lastModifiedDate), className: `btn btn-app btn-link case-reply-button ${isExportingPDF ? 'hide-in-pdf' : ''}`, "data-tracking-id": "case-comment-reply", type: "button" },
|
|
291
|
+
React.createElement(Trans, null, "Reply"))),
|
|
292
|
+
React.createElement(JumpAndCopyLink, { caseNumber: caseNumber, cardId: props.comment.id, discussionType: DiscussionType.COMMENT }))),
|
|
293
|
+
isAsaComment && (React.createElement(AsaCommentFeedbackModal, { isOpen: isAsaFeedbackModalOpen, isSubmitting: isFeedbackUpdating, initialFeedback: savedFeedbackValue, initialFeedbackReason: savedFeedbackReason, onClose: () => setIsAsaFeedbackModalOpen(false), onSubmit: onSubmitAsaFeedback }))));
|
|
287
294
|
});
|
|
288
295
|
export default CaseComments;
|
|
@@ -1 +1 @@
|
|
|
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;AAqBvE,OAAO,KAA0F,MAAM,OAAO,CAAC;
|
|
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;AAqBvE,OAAO,KAA0F,MAAM,OAAO,CAAC;AA2C/G,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;IAC/C,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,MAAM,qBA83BnD"}
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { useApolloClient } from '@apollo/client/react';
|
|
11
|
-
import { Button, MenuToggle, Select, SelectList, SelectOption } from '@patternfly/react-core';
|
|
11
|
+
import { Alert, Button, MenuToggle, Select, SelectList, SelectOption } from '@patternfly/react-core';
|
|
12
12
|
import { AlertMessage, AlertType, ErrorBoundary, LoadingIndicator, ToastNotification } from '@rh-support/components';
|
|
13
13
|
import { useGlobalStateContext } from '@rh-support/react-context';
|
|
14
14
|
import { AbilityContext, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
@@ -29,19 +29,18 @@ import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContex
|
|
|
29
29
|
import { useCaseDetailsPageDispatchContext, useCaseDetailsPageStateContext, } from '../../../../context/CaseDetailsPageContext';
|
|
30
30
|
import { useCaseDiscussionTabDispatchContext, useCaseDiscussionTabStateContext, } from '../../../../context/CaseDiscussionTabContext';
|
|
31
31
|
import { CaseDetailsConstants } from '../../../../reducers/CaseDetailsPageReducer';
|
|
32
|
-
import { clearReplyingTo, discussionSortOrderConst, DiscussionType, setDiscussions, setFilter, setReplyingTo, setSort, updateAttachment, updateAttacmentsAfterRemoval, updateDiscussionStateAttachments, } from '../../../../reducers/CaseDiscussionTabReducer';
|
|
32
|
+
import { clearReplyingTo, commputeFeedback, computeFeedbackReason, discussionSortOrderConst, DiscussionType, setDiscussions, setFilter, setReplyingTo, setSort, updateAttachment, updateAttacmentsAfterRemoval, updateDiscussionStateAttachments, } from '../../../../reducers/CaseDiscussionTabReducer';
|
|
33
33
|
import { setCaseState } from '../../../../reducers/CaseReducer';
|
|
34
34
|
import { AttachmentContextProvider } from '../../../shared/fileUpload/reducer/AttachmentReducerContext';
|
|
35
35
|
import { PDFContext } from '../../PDFContainer';
|
|
36
36
|
import CaseAttachment from './CaseAttachment';
|
|
37
|
-
import CaseComments from './CaseComments';
|
|
37
|
+
import CaseComments, { AUTOMATED_SUPPORT_ASSISTANT } from './CaseComments';
|
|
38
38
|
// import CaseExternalTrackerUpdate from './CaseExternalTrackerUpdate';
|
|
39
39
|
import { CommentSearch } from './CommentSearch';
|
|
40
40
|
import { PostComment } from './PostComment';
|
|
41
41
|
/** Threshold above which comments render in a virtualized (windowed) list for performance. */
|
|
42
42
|
const VC_MINIMUM_COMMENT = 150;
|
|
43
43
|
export default function CaseDiscussion(props) {
|
|
44
|
-
var _a;
|
|
45
44
|
const { t } = useTranslation();
|
|
46
45
|
const { isPostingRemoteRequestCommentCompleted, product, version, caseSalesforceId } = useCaseSelector((state) => ({
|
|
47
46
|
isPostingRemoteRequestCommentCompleted: state.isPostingRemoteRequestCommentCompleted,
|
|
@@ -55,7 +54,7 @@ export default function CaseDiscussion(props) {
|
|
|
55
54
|
const { sort, discussionFiltersListState, replyingToAuthor, replyingToTimestamp } = useCaseDiscussionTabStateContext();
|
|
56
55
|
const { globalMetadataState: { navBarRef, loggedInUsersAccount }, } = useGlobalStateContext();
|
|
57
56
|
const dispatchDiscussion = useCaseDiscussionTabDispatchContext();
|
|
58
|
-
const { caseDetailsPageState: { caseAttachmentHydra }, } = useCaseDetailsPageStateContext();
|
|
57
|
+
const { caseDetailsPageState: { caseAttachmentHydra, caseFeedbacksHydra }, } = useCaseDetailsPageStateContext();
|
|
59
58
|
const dispatchCaseDetailsHydraAttachments = useCaseDetailsPageDispatchContext();
|
|
60
59
|
const caseDispatch = useCaseDispatch();
|
|
61
60
|
const apolloClient = useApolloClient();
|
|
@@ -81,6 +80,7 @@ export default function CaseDiscussion(props) {
|
|
|
81
80
|
const [selectedFilterItems, setSelectedFilterItems] = useState([]);
|
|
82
81
|
const [isSortOpen, setIsSortOpen] = useState(false);
|
|
83
82
|
const [sortSelected, setSortSelected] = useState('Select a value');
|
|
83
|
+
const [localFeedbackOverrides, setLocalFeedbackOverrides] = useState({});
|
|
84
84
|
const { hasNextPage, isLoadingMore, loadMoreError, fetchMore } = props;
|
|
85
85
|
const isCommentFilterActive = discussionFiltersListState.some((f) => (f.value === DiscussionType.COMMENT || f.value === DiscussionType.ALL) && f.isSelected);
|
|
86
86
|
useEffect(() => {
|
|
@@ -111,13 +111,20 @@ export default function CaseDiscussion(props) {
|
|
|
111
111
|
const cellMeasureCache = cellMeasureCacheRef.current;
|
|
112
112
|
const allDiscussions = useMemo(() => {
|
|
113
113
|
var _a, _b, _c;
|
|
114
|
+
const feedbacks = caseFeedbacksHydra.data || [];
|
|
114
115
|
const allComments = (props.caseComments || [])
|
|
115
116
|
.filter((comment) => comment.isDraft === false)
|
|
116
|
-
.map((comment) =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
.map((comment) => {
|
|
118
|
+
var _a, _b;
|
|
119
|
+
const localOverride = localFeedbackOverrides[comment.id];
|
|
120
|
+
return {
|
|
121
|
+
item: Object.assign(Object.assign({}, comment), { isPublic: comment.isPublic === undefined ? true : comment.isPublic, last_modified_date: comment.lastModifiedDate || comment.createdDate }),
|
|
122
|
+
discussionType: DiscussionType.COMMENT,
|
|
123
|
+
last_modified_date: comment.lastModifiedDate || comment.createdDate,
|
|
124
|
+
feedback: (_a = localOverride === null || localOverride === void 0 ? void 0 : localOverride.feedback) !== null && _a !== void 0 ? _a : commputeFeedback(comment.id, feedbacks),
|
|
125
|
+
feedbackReason: (_b = localOverride === null || localOverride === void 0 ? void 0 : localOverride.feedbackReason) !== null && _b !== void 0 ? _b : computeFeedbackReason(comment.id, feedbacks),
|
|
126
|
+
};
|
|
127
|
+
});
|
|
121
128
|
let allAttachments = canSeeAttachments
|
|
122
129
|
? (caseAttachmentHydra.data || [])
|
|
123
130
|
.filter((attachment) => (attachment === null || attachment === void 0 ? void 0 : attachment.lastModifiedDate) || (attachment === null || attachment === void 0 ? void 0 : attachment.createdDate))
|
|
@@ -143,12 +150,21 @@ export default function CaseDiscussion(props) {
|
|
|
143
150
|
}
|
|
144
151
|
const merged = [...allComments, ...allAttachments];
|
|
145
152
|
return orderBy(merged, ['last_modified_date', (d) => { var _a; return (_a = d.item.id) !== null && _a !== void 0 ? _a : ''; }], [(_b = sort === null || sort === void 0 ? void 0 : sort.sortOrder) !== null && _b !== void 0 ? _b : 'desc', (_c = sort === null || sort === void 0 ? void 0 : sort.sortOrder) !== null && _c !== void 0 ? _c : 'desc']);
|
|
146
|
-
}, [
|
|
153
|
+
}, [
|
|
154
|
+
props.caseComments,
|
|
155
|
+
caseAttachmentHydra.data,
|
|
156
|
+
caseFeedbacksHydra.data,
|
|
157
|
+
localFeedbackOverrides,
|
|
158
|
+
canSeeAttachments,
|
|
159
|
+
sort,
|
|
160
|
+
props.hasNextPage,
|
|
161
|
+
]);
|
|
147
162
|
const usedPaginationRef = useRef(false);
|
|
148
163
|
if (props.hasNextPage || props.isLoadingMore) {
|
|
149
164
|
usedPaginationRef.current = true;
|
|
150
165
|
}
|
|
151
166
|
const shouldRenderRVComponent = !isExportingPDF && allDiscussions.length > VC_MINIMUM_COMMENT && !usedPaginationRef.current;
|
|
167
|
+
const hasAsaComment = (props.caseComments || []).some((comment) => (comment === null || comment === void 0 ? void 0 : comment.createdBy) === AUTOMATED_SUPPORT_ASSISTANT);
|
|
152
168
|
const list = discussionFiltersListState.filter((f) => f.canSee);
|
|
153
169
|
const computeFilterComment = () => {
|
|
154
170
|
return filter(allDiscussions, (discussion) => {
|
|
@@ -164,21 +180,6 @@ export default function CaseDiscussion(props) {
|
|
|
164
180
|
const isSearchResultEmpty = !isRefetching &&
|
|
165
181
|
!isEmpty(searchCommentText) &&
|
|
166
182
|
(searchResult.length === 0 || comuteSearchedComments.length === 0);
|
|
167
|
-
// DEBUG: track every render of CaseDiscussion
|
|
168
|
-
console.log('[CaseDiscussion] render', {
|
|
169
|
-
commentsLoading: props.commentsLoading,
|
|
170
|
-
isLoadingMore: props.isLoadingMore,
|
|
171
|
-
hasNextPage: props.hasNextPage,
|
|
172
|
-
loadMoreError: props.loadMoreError,
|
|
173
|
-
isRefetching,
|
|
174
|
-
isSearchResultEmpty,
|
|
175
|
-
allDiscussionsLen: allDiscussions.length,
|
|
176
|
-
filteredLen: computeFilteredComments.length,
|
|
177
|
-
searchedLen: comuteSearchedComments.length,
|
|
178
|
-
caseCommentsLen: (_a = props.caseComments) === null || _a === void 0 ? void 0 : _a.length,
|
|
179
|
-
inView,
|
|
180
|
-
isCommentFilterActive,
|
|
181
|
-
});
|
|
182
183
|
const setVRCommentIndex = (cId) => {
|
|
183
184
|
setCommentIndex(cId < 0 ? 0 : cId);
|
|
184
185
|
setJumpToCommentClicked(true);
|
|
@@ -247,14 +248,25 @@ export default function CaseDiscussion(props) {
|
|
|
247
248
|
useEffect(() => {
|
|
248
249
|
if (isExportingPDF)
|
|
249
250
|
return;
|
|
250
|
-
|
|
251
|
+
if (caseAttachmentHydra.isFetching || caseFeedbacksHydra.isFetching)
|
|
252
|
+
return;
|
|
253
|
+
setDiscussions(dispatchDiscussion, props.caseComments, [], caseAttachmentHydra.data, caseFeedbacksHydra.data, [], discussionFiltersListState, false, false, canSeeAttachments, sort);
|
|
251
254
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
252
|
-
}, [props.caseComments, caseAttachmentHydra, canSeeAttachments, sort]);
|
|
255
|
+
}, [props.caseComments, caseAttachmentHydra, caseFeedbacksHydra, canSeeAttachments, sort]);
|
|
253
256
|
useEffect(() => {
|
|
254
257
|
if (!caseAttachmentHydra.isFetching && caseAttachmentHydra.isError) {
|
|
255
258
|
ToastNotification.addDangerMessage(t('There was an error loading attachments.'));
|
|
256
259
|
}
|
|
257
|
-
|
|
260
|
+
if (!caseFeedbacksHydra.isFetching && caseFeedbacksHydra.isError) {
|
|
261
|
+
ToastNotification.addDangerMessage(t('There was an error loading feedback.'));
|
|
262
|
+
}
|
|
263
|
+
}, [
|
|
264
|
+
caseAttachmentHydra.isFetching,
|
|
265
|
+
caseAttachmentHydra.isError,
|
|
266
|
+
caseFeedbacksHydra.isFetching,
|
|
267
|
+
caseFeedbacksHydra.isError,
|
|
268
|
+
t,
|
|
269
|
+
]);
|
|
258
270
|
const onCommentAdded = () => __awaiter(this, void 0, void 0, function* () {
|
|
259
271
|
try {
|
|
260
272
|
yield props.refetchComments();
|
|
@@ -264,6 +276,9 @@ export default function CaseDiscussion(props) {
|
|
|
264
276
|
}
|
|
265
277
|
dtmTrackEventCaseStepEncountered('comment', caseNumber, product, version);
|
|
266
278
|
});
|
|
279
|
+
const onFeedbackUpdate = (comment_id, feedback, feedbackReason) => {
|
|
280
|
+
setLocalFeedbackOverrides((prev) => (Object.assign(Object.assign({}, prev), { [comment_id]: { feedback, feedbackReason } })));
|
|
281
|
+
};
|
|
267
282
|
const onReply = (author, commentId, timestamp) => {
|
|
268
283
|
setReplyingTo(dispatchDiscussion, author, commentId, timestamp);
|
|
269
284
|
scrollIntoView(props.tabRef, { navBarRef, timeout: 0, onlyIfNotInViewport: true, offset: 30 });
|
|
@@ -386,7 +401,7 @@ export default function CaseDiscussion(props) {
|
|
|
386
401
|
if (isEmpty(discussion) || isEmpty(discussion.item))
|
|
387
402
|
return null;
|
|
388
403
|
return (React.createElement("div", { "data-tracking-id": "discussion-elements", key: discussion.item.id },
|
|
389
|
-
discussion.discussionType === DiscussionType.COMMENT && (React.createElement(CaseComments, { caseNumber: caseNumber, ref: discussionIdFromUrl === discussion.item.id ? activeDiscussionElementRef : null, comment: discussion.item, onFeedBackUpdate:
|
|
404
|
+
discussion.discussionType === DiscussionType.COMMENT && (React.createElement(CaseComments, { caseNumber: caseNumber, ref: discussionIdFromUrl === discussion.item.id ? activeDiscussionElementRef : null, comment: discussion.item, onFeedBackUpdate: onFeedbackUpdate, feedback: discussion.feedback, feedbackReason: discussion.feedbackReason, accountNumber: props.accountNumber, onReply: onReply, showJumpToComment: !isEmpty(searchCommentText), onJumpToComment: onJumpToComment, downloadAttachment: downloadAttachment })),
|
|
390
405
|
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 }))));
|
|
391
406
|
};
|
|
392
407
|
const rowRenderer = ({ index, parent, key, style, }) => {
|
|
@@ -482,28 +497,11 @@ export default function CaseDiscussion(props) {
|
|
|
482
497
|
};
|
|
483
498
|
const onSortToggle = (toggleRef) => (React.createElement(MenuToggle, { ref: toggleRef, onClick: onSortToggleClick, isExpanded: isSortOpen, isFullWidth: true }, sort.name));
|
|
484
499
|
return (React.createElement(React.Fragment, null,
|
|
485
|
-
(()
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const showNoMore = !props.hasNextPage &&
|
|
491
|
-
!props.isLoadingMore &&
|
|
492
|
-
!props.commentsLoading &&
|
|
493
|
-
!props.loadMoreError &&
|
|
494
|
-
comuteSearchedComments.length > 0;
|
|
495
|
-
console.log('[CaseDiscussion] RENDER DECISION', {
|
|
496
|
-
showInitialLoading,
|
|
497
|
-
showNoComments,
|
|
498
|
-
showDiscussions,
|
|
499
|
-
isRefetching,
|
|
500
|
-
showSkeleton,
|
|
501
|
-
showNoMore,
|
|
502
|
-
isSearchResultEmpty,
|
|
503
|
-
shouldRenderRVComponent,
|
|
504
|
-
});
|
|
505
|
-
return null;
|
|
506
|
-
})(),
|
|
500
|
+
hasAsaComment && (React.createElement(Alert, { className: `asa-discussion-alert ${isExportingPDF ? 'hide-in-pdf' : ''}`, isInline: true, variant: "info", title: t('Important'), "data-tracking-id": "case-discussion-asa-notice" },
|
|
501
|
+
React.createElement(Trans, null,
|
|
502
|
+
"This feature uses AI technology to analyze interactions and provide you with support. Interactions may be used to improve Red Hat products or services. For more information about Red Hat's privacy practices, please refer to the",
|
|
503
|
+
' ',
|
|
504
|
+
React.createElement("a", { href: "https://www.redhat.com/en/about/privacy-policy", target: "_blank", rel: "noopener noreferrer" }, "Red Hat Privacy Statement")))),
|
|
507
505
|
React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading post comment section') } },
|
|
508
506
|
React.createElement(AttachmentContextProvider, null,
|
|
509
507
|
React.createElement(PostComment, { caseNumber: caseNumber, allDiscussions: allDiscussions, onCommentAdded: onCommentAdded, onAttachmentAdded: onAttachmentAdded, onAttachmentRemove: onAttachmentRemove, replyingToAuthor: replyingToAuthor, replyingToTimestamp: replyingToTimestamp, onClearReply: onClearReply }))),
|
package/lib/esm/css/case.css
CHANGED
|
@@ -114,13 +114,21 @@ button,
|
|
|
114
114
|
gap: 8px;
|
|
115
115
|
font-size: 18px;
|
|
116
116
|
font-weight: 500;
|
|
117
|
+
line-height: 1.2;
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
.asa-comment-author {
|
|
121
|
+
display: inline-flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
min-width: 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.asa-comment-author-icon {
|
|
127
|
+
width: 16px;
|
|
128
|
+
height: 16px;
|
|
122
129
|
flex-shrink: 0;
|
|
123
|
-
|
|
130
|
+
display: block;
|
|
131
|
+
margin-right: 8px;
|
|
124
132
|
}
|
|
125
133
|
|
|
126
134
|
.support-comment.comment-automated .asa-comment-alert.pf-v6-c-alert {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCaseComments.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useCaseComments/useCaseComments.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAOvE,OAAO,EAAuB,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,IAAI,EACJ,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,GACR,EAAE,uBAAuB,GAAG,sBAAsB,
|
|
1
|
+
{"version":3,"file":"useCaseComments.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useCaseComments/useCaseComments.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAOvE,OAAO,EAAuB,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,IAAI,EACJ,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,GACR,EAAE,uBAAuB,GAAG,sBAAsB,CAkGlD"}
|
|
@@ -28,7 +28,7 @@ function buildCaseCommentsFilter(caseId, publicOnly) {
|
|
|
28
28
|
* result so cache-and-network does not refetch and overwrite merged pages.
|
|
29
29
|
*/
|
|
30
30
|
export function useCaseComments({ caseId, skip, orderBy, first, publicOnly, after, }) {
|
|
31
|
-
var _a, _b, _c, _d, _e
|
|
31
|
+
var _a, _b, _c, _d, _e;
|
|
32
32
|
const canSeePrivateComments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.VIEW_PRIVATE_COMMENT);
|
|
33
33
|
const shouldFilterPublicOnly = publicOnly !== null && publicOnly !== void 0 ? publicOnly : !canSeePrivateComments;
|
|
34
34
|
const clampedFirst = clamp(first !== null && first !== void 0 ? first : DEFAULT_PAGE_SIZE, MIN_FIRST, MAX_FIRST);
|
|
@@ -52,18 +52,6 @@ export function useCaseComments({ caseId, skip, orderBy, first, publicOnly, afte
|
|
|
52
52
|
const endCursor = (_e = pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.endCursor) !== null && _e !== void 0 ? _e : null;
|
|
53
53
|
const isLoadingMore = networkStatus === NetworkStatus.fetchMore;
|
|
54
54
|
const comments = useMemo(() => mapCaseCommentsResponse(data), [data]);
|
|
55
|
-
// DEBUG: track every render of the hook
|
|
56
|
-
const edgeCount = (_k = (_j = (_h = (_g = (_f = data === null || data === void 0 ? void 0 : data.redhat_support_uiapi) === null || _f === void 0 ? void 0 : _f.query) === null || _g === void 0 ? void 0 : _g.RedHatSupportCaseComment__c) === null || _h === void 0 ? void 0 : _h.edges) === null || _j === void 0 ? void 0 : _j.length) !== null && _k !== void 0 ? _k : 0;
|
|
57
|
-
console.log('[useCaseComments] render', {
|
|
58
|
-
networkStatus,
|
|
59
|
-
loading,
|
|
60
|
-
isLoadingMore,
|
|
61
|
-
hasNextPage,
|
|
62
|
-
endCursor: endCursor === null || endCursor === void 0 ? void 0 : endCursor.slice(0, 20),
|
|
63
|
-
edgeCount,
|
|
64
|
-
commentsMapped: comments.length,
|
|
65
|
-
fetchLocked: fetchLockRef.current,
|
|
66
|
-
});
|
|
67
55
|
const fetchMore = useCallback(() => {
|
|
68
56
|
if (fetchLockRef.current || !hasNextPage || !endCursor) {
|
|
69
57
|
console.log('[useCaseComments] fetchMore SKIPPED', {
|
|
@@ -10,6 +10,7 @@ export interface IDiscussion {
|
|
|
10
10
|
last_modified_date: string;
|
|
11
11
|
discussionType: string;
|
|
12
12
|
feedback?: number;
|
|
13
|
+
feedbackReason?: string;
|
|
13
14
|
}
|
|
14
15
|
export declare enum DiscussionType {
|
|
15
16
|
COMMENT = "comment",
|
|
@@ -48,10 +49,12 @@ export declare const setSort: (dispatch: DiscussionsReducerDispatchType, sort: I
|
|
|
48
49
|
export declare const setReplyingTo: (dispatch: DiscussionsReducerDispatchType, author: string, commentId: string, timestamp: string) => void;
|
|
49
50
|
export declare const clearReplyingTo: (dispatch: DiscussionsReducerDispatchType) => void;
|
|
50
51
|
export declare const setFilter: (dispatch: DiscussionsReducerDispatchType, selected: string[], discussionFiltersListState: IFilter[]) => void;
|
|
52
|
+
export declare const commputeFeedback: (commentId: string, feedbacks: ICommentFeedback[]) => number;
|
|
53
|
+
export declare const computeFeedbackReason: (commentId: string, feedbacks: ICommentFeedback[]) => string | undefined;
|
|
51
54
|
export declare const setDiscussions: (dispatch: DiscussionsReducerDispatchType, comments: ICaseComment[], chats: ICaseChat[], attachments: IAttachment[], feedbacks: ICommentFeedback[], trackerUpdates: Partial<unknown[]>, discussionFiltersListState: IFilter[], canSeeExternalTracker: boolean, canSeeChat: boolean, canSeeAttachments: boolean, sort?: ISort) => void;
|
|
52
55
|
export declare const appendNewComments: (dispatch: DiscussionsReducerDispatchType, allComments: ICaseComment[], existingDiscussions: IDiscussion[], feedbacks: ICommentFeedback[], sort?: ISort) => void;
|
|
53
56
|
export declare const updateAttacmentsAfterRemoval: (dispatch: DiscussionsReducerDispatchType, uuid_removed: string, allDiscussions: IDiscussion[], discussionFiltersListState: IFilter[]) => void;
|
|
54
|
-
export declare const updateCommentStateFeedback: (dispatch: DiscussionsReducerDispatchType, comment_id: string, newFeedback: any, allDiscussions: IDiscussion[]) => Promise<void>;
|
|
57
|
+
export declare const updateCommentStateFeedback: (dispatch: DiscussionsReducerDispatchType, comment_id: string, newFeedback: any, allDiscussions: IDiscussion[], feedbackReason?: string) => Promise<void>;
|
|
55
58
|
export declare const updateAttachment: (dispatch: DiscussionsReducerDispatchType, uuid: string, newAttachment: any, allDiscussions: IDiscussion[]) => void;
|
|
56
59
|
export declare const updateDiscussionStateAttachments: (dispatch: DiscussionsReducerDispatchType, caseNumber: string, allDiscussions: IDiscussion[], sort: ISort, discussionFiltersListState: IFilter[], dispatchCaseDetailsHydraAttachments: any, apolloClient: ApolloQueryClient, caseSalesforceId?: string, includeSecureSupport?: boolean) => Promise<void>;
|
|
57
60
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseDiscussionTabReducer.d.ts","sourceRoot":"","sources":["../../../src/reducers/CaseDiscussionTabReducer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EACH,iBAAiB,EAKpB,MAAM,mBAAmB,CAAC;AAQ3B,KAAK,WAAW,GAAG,OAAO,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC;AACnE,MAAM,MAAM,8BAA8B,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAE1E,MAAM,WAAW,WAAW;IAGxB,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC,CAAC;IACtD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseDiscussionTabReducer.d.ts","sourceRoot":"","sources":["../../../src/reducers/CaseDiscussionTabReducer.ts"],"names":[],"mappings":"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"}
|
|
@@ -132,10 +132,14 @@ export const setFilter = (dispatch, selected, discussionFiltersListState) => {
|
|
|
132
132
|
dispatch({ type: DiscussionsConstants.updateDiscussionState, payload: { discussionFiltersListState } });
|
|
133
133
|
}
|
|
134
134
|
};
|
|
135
|
-
const commputeFeedback = (commentId, feedbacks) => {
|
|
135
|
+
export const commputeFeedback = (commentId, feedbacks) => {
|
|
136
136
|
const feedback = feedbacks.filter((feedback) => feedback.commentId === commentId);
|
|
137
137
|
return feedback.length === 0 ? undefined : parseInt(feedback[0].feedback);
|
|
138
138
|
};
|
|
139
|
+
export const computeFeedbackReason = (commentId, feedbacks) => {
|
|
140
|
+
const feedback = (feedbacks || []).find((item) => item.commentId === commentId);
|
|
141
|
+
return feedback === null || feedback === void 0 ? void 0 : feedback.feedbackReason;
|
|
142
|
+
};
|
|
139
143
|
export const setDiscussions = (dispatch, comments, chats, attachments, feedbacks,
|
|
140
144
|
// TODO: Uncomment when External Trackers has a functioning GraphQL endpoint
|
|
141
145
|
// trackerUpdates: Partial<IExternalTrackerUpdate[]>,
|
|
@@ -160,6 +164,7 @@ canSeeExternalTracker, canSeeChat, canSeeAttachments, sort) => {
|
|
|
160
164
|
discussionType: DiscussionType.COMMENT,
|
|
161
165
|
last_modified_date: comment.lastModifiedDate || comment.createdDate,
|
|
162
166
|
feedback: commputeFeedback(comment.id, feedbacks),
|
|
167
|
+
feedbackReason: computeFeedbackReason(comment.id, feedbacks),
|
|
163
168
|
}));
|
|
164
169
|
// TODO: Uncomment when External Trackers has a functioning GraphQL endpoint
|
|
165
170
|
// const allExternalTrackers: IDiscussion[] = (trackerUpdates || []).map((externalUpdate) => ({
|
|
@@ -223,6 +228,7 @@ export const appendNewComments = (dispatch, allComments, existingDiscussions, fe
|
|
|
223
228
|
discussionType: DiscussionType.COMMENT,
|
|
224
229
|
last_modified_date: comment.lastModifiedDate || comment.createdDate,
|
|
225
230
|
feedback: commputeFeedback(comment.id, feedbacks),
|
|
231
|
+
feedbackReason: computeFeedbackReason(comment.id, feedbacks),
|
|
226
232
|
}));
|
|
227
233
|
const sortOrder = (_a = sort === null || sort === void 0 ? void 0 : sort.sortOrder) !== null && _a !== void 0 ? _a : 'desc';
|
|
228
234
|
const merged = sortOrder === 'desc'
|
|
@@ -247,10 +253,13 @@ export const updateAttacmentsAfterRemoval = (dispatch, uuid_removed, allDiscussi
|
|
|
247
253
|
dispatch({ type: DiscussionsConstants.updateDiscussionState, payload: { discussionFiltersListState } });
|
|
248
254
|
dispatch({ type: DiscussionsConstants.updateDiscussionState, payload: { allDiscussions } });
|
|
249
255
|
};
|
|
250
|
-
export const updateCommentStateFeedback = (dispatch, comment_id, newFeedback, allDiscussions) => __awaiter(void 0, void 0, void 0, function* () {
|
|
256
|
+
export const updateCommentStateFeedback = (dispatch, comment_id, newFeedback, allDiscussions, feedbackReason) => __awaiter(void 0, void 0, void 0, function* () {
|
|
251
257
|
const updateDiscussions = allDiscussions.map((discussion) => {
|
|
252
258
|
if (discussion.discussionType === DiscussionType.COMMENT && discussion.item.id === comment_id) {
|
|
253
259
|
discussion.feedback = newFeedback;
|
|
260
|
+
if (feedbackReason !== undefined) {
|
|
261
|
+
discussion.feedbackReason = feedbackReason;
|
|
262
|
+
}
|
|
254
263
|
}
|
|
255
264
|
return discussion;
|
|
256
265
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rh-support/troubleshoot",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.13",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"@progress/kendo-licensing": "1.3.5",
|
|
53
53
|
"@progress/kendo-react-pdf": "^5.16.0",
|
|
54
54
|
"@redux-devtools/extension": "^3.3.0",
|
|
55
|
-
"@rh-support/components": "2.6.
|
|
56
|
-
"@rh-support/react-context": "2.6.
|
|
55
|
+
"@rh-support/components": "2.6.13",
|
|
56
|
+
"@rh-support/react-context": "2.6.13",
|
|
57
57
|
"@rh-support/types": "2.0.26",
|
|
58
|
-
"@rh-support/user-permissions": "2.
|
|
59
|
-
"@rh-support/utils": "2.6.
|
|
58
|
+
"@rh-support/user-permissions": "2.6.11",
|
|
59
|
+
"@rh-support/utils": "2.6.11",
|
|
60
60
|
"@types/react-redux": "^7.1.33",
|
|
61
61
|
"@types/redux": "^3.6.0",
|
|
62
62
|
"date-fns": "3.6.0",
|
|
@@ -129,5 +129,5 @@
|
|
|
129
129
|
"defaults and supports es6-module",
|
|
130
130
|
"maintained node versions"
|
|
131
131
|
],
|
|
132
|
-
"gitHead": "
|
|
132
|
+
"gitHead": "62c47bc5a96582980baf93fe038f4a1129cabaaf"
|
|
133
133
|
}
|