@rh-support/components 2.5.230 → 2.6.10
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupportFeedbackModal.d.ts","sourceRoot":"","sources":["../../../src/SupportFeedbackForm/SupportFeedbackModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SupportFeedbackModal.d.ts","sourceRoot":"","sources":["../../../src/SupportFeedbackForm/SupportFeedbackModal.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAcnD,UAAU,MAAM;IACZ,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CAC1B;AAWD,iBAAS,oBAAoB,CAAC,KAAK,EAAE,MAAM,qBA+S1C;kBA/SQ,oBAAoB;;;AAkT7B,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { pcm } from '@cee-eng/hydrajs';
|
|
11
|
-
import { Button, Icon, Modal, ModalBody, ModalFooter, ModalHeader, ModalVariant } from '@patternfly/react-core';
|
|
11
|
+
import { Button, FormGroup, FormHelperText, HelperText, HelperTextItem, Icon, Modal, ModalBody, ModalFooter, ModalHeader, ModalVariant, TextArea, ValidatedOptions, } from '@patternfly/react-core';
|
|
12
12
|
import OutlinedFrownIcon from '@patternfly/react-icons/dist/js/icons/outlined-frown-icon';
|
|
13
13
|
import OutlinedFrownOpenIcon from '@patternfly/react-icons/dist/js/icons/outlined-frown-open-icon';
|
|
14
14
|
import OutlinedGrinIcon from '@patternfly/react-icons/dist/js/icons/outlined-grin-icon';
|
|
@@ -20,11 +20,16 @@ import React, { useEffect, useState } from 'react';
|
|
|
20
20
|
import { Trans, useTranslation } from 'react-i18next';
|
|
21
21
|
import { useLocation, useParams } from 'react-router-dom';
|
|
22
22
|
import { useFetch } from '../hooks/useFetch';
|
|
23
|
-
import { TextAreaAutosize } from '../TextAreaAutosize';
|
|
24
23
|
import { ToastNotification } from '../ToastNotification';
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
function isRequiredFieldValid(key, value) {
|
|
25
|
+
if (key === 'moreInfo') {
|
|
26
|
+
return (value !== null && value !== void 0 ? value : '').trim().length > 0;
|
|
27
|
+
}
|
|
28
|
+
return !isEmpty(value);
|
|
29
|
+
}
|
|
30
|
+
const formInitState = {
|
|
31
|
+
levelOfSatisfied: null,
|
|
32
|
+
moreInfo: '',
|
|
28
33
|
};
|
|
29
34
|
const defaultProps = {
|
|
30
35
|
isModalOpen: false,
|
|
@@ -34,29 +39,25 @@ function SupportFeedbackModal(props) {
|
|
|
34
39
|
const { t } = useTranslation();
|
|
35
40
|
const seSessionId = (_b = (_a = getUrlParsedParams(useLocation().search)) === null || _a === void 0 ? void 0 : _a.seSessionId) !== null && _b !== void 0 ? _b : '';
|
|
36
41
|
const { caseNumber } = useParams();
|
|
37
|
-
const formInitState = {
|
|
38
|
-
levelOfSatisfied: null,
|
|
39
|
-
moreInfo: '',
|
|
40
|
-
};
|
|
41
42
|
const [values, setValues] = useState(formInitState);
|
|
42
43
|
const { request: requestAISummary, isFetching: isFetchingAISummary } = useFetch(pcm.AISummaryFeedback, {
|
|
43
44
|
propgateErrors: true,
|
|
44
45
|
});
|
|
45
|
-
const { request:
|
|
46
|
+
const { request: requestPcmFeedback, isFetching: isFetchingFeedback } = useFetch(pcm.submitPcmFeedback, {
|
|
46
47
|
propgateErrors: true,
|
|
47
48
|
});
|
|
48
49
|
const isFetching = isFetchingAISummary || isFetchingFeedback;
|
|
49
|
-
const [
|
|
50
|
-
const [
|
|
50
|
+
const [showRatingError, setShowRatingError] = useState(false);
|
|
51
|
+
const [showFeedbackTextError, setShowFeedbackTextError] = useState(false);
|
|
52
|
+
const trimmedMoreInfo = values.moreInfo.trim();
|
|
53
|
+
const hasValidationError = showRatingError || showFeedbackTextError;
|
|
51
54
|
useEffect(() => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
setSubmitButtonValid(!valid);
|
|
59
|
-
}, [values]);
|
|
55
|
+
setShowRatingError(false);
|
|
56
|
+
setShowFeedbackTextError(false);
|
|
57
|
+
if (!props.isModalOpen) {
|
|
58
|
+
setValues(formInitState);
|
|
59
|
+
}
|
|
60
|
+
}, [props.isModalOpen]);
|
|
60
61
|
useEffect(() => {
|
|
61
62
|
if (props.caseSummaryId) {
|
|
62
63
|
setValues((prev) => (Object.assign(Object.assign({}, prev), { caseSummaryId: props.caseSummaryId })));
|
|
@@ -67,59 +68,75 @@ function SupportFeedbackModal(props) {
|
|
|
67
68
|
}, [props.caseSummaryId, props.errorMessage]);
|
|
68
69
|
// To Handle the Feedback Satisfaction values
|
|
69
70
|
const handleSentimentChange = (event) => {
|
|
70
|
-
|
|
71
|
+
setShowRatingError(false);
|
|
71
72
|
setValues(Object.assign(Object.assign({}, values), { [event.target.name]: event.target.value }));
|
|
72
73
|
};
|
|
73
74
|
// To Handle the Text Area Input (Feedback Description)
|
|
74
|
-
const handleFeedbackTextChange = (
|
|
75
|
-
|
|
75
|
+
const handleFeedbackTextChange = (_event, value) => {
|
|
76
|
+
setShowFeedbackTextError(false);
|
|
77
|
+
setValues(Object.assign(Object.assign({}, values), { moreInfo: value }));
|
|
76
78
|
};
|
|
77
79
|
// To handle submit
|
|
78
80
|
const handleSubmit = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
79
81
|
var _a;
|
|
80
82
|
event.preventDefault();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
updatedValues = Object.assign(Object.assign({}, updatedValues), { moreInfo: `${extraInfo.filter(Boolean).join('')}${updatedValues.moreInfo || ''}`.trim() });
|
|
98
|
-
delete updatedValues.caseSummaryErrorMessage;
|
|
99
|
-
delete updatedValues.caseSummaryId;
|
|
100
|
-
const emojiRegex = /(\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Extended_Pictographic})+/gu;
|
|
101
|
-
updatedValues.moreInfo = (_a = updatedValues.moreInfo) === null || _a === void 0 ? void 0 : _a.replace(emojiRegex, (match) => encodeURIComponent(match));
|
|
102
|
-
// Call the request with the updated values
|
|
103
|
-
yield requestFeedbackForm(updatedValues, window.sessionjs, window.location.href, seSessionId);
|
|
104
|
-
}
|
|
105
|
-
setValues(formInitState); // Reset form state after successful submission
|
|
106
|
-
ToastNotification.addSuccessMessage(t(`Thank you. We've received your feedback.`), t('Have a great day!'));
|
|
107
|
-
handleModalToggle();
|
|
83
|
+
const hasRating = isRequiredFieldValid('levelOfSatisfied', values.levelOfSatisfied);
|
|
84
|
+
const hasFeedbackText = trimmedMoreInfo.length > 0;
|
|
85
|
+
setShowRatingError(!hasRating);
|
|
86
|
+
setShowFeedbackTextError(!hasFeedbackText);
|
|
87
|
+
if (!hasRating || !hasFeedbackText) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let updatedValues = Object.assign(Object.assign({}, values), { moreInfo: trimmedMoreInfo });
|
|
91
|
+
try {
|
|
92
|
+
if (props.isCaseSummary) {
|
|
93
|
+
const aiPayload = {
|
|
94
|
+
caseNumber: caseNumber || '',
|
|
95
|
+
feedback: values.levelOfSatisfied || '',
|
|
96
|
+
description: trimmedMoreInfo,
|
|
97
|
+
};
|
|
98
|
+
yield requestAISummary(aiPayload, window.sessionjs);
|
|
108
99
|
}
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
else {
|
|
101
|
+
const extraInfo = [
|
|
102
|
+
props.errorMessage && `caseSummaryErrorMessage:'${props.errorMessage}'\n`,
|
|
103
|
+
props.caseSummaryId && `caseSummaryId:'${props.caseSummaryId}'\n`,
|
|
104
|
+
];
|
|
105
|
+
updatedValues = Object.assign(Object.assign({}, updatedValues), { moreInfo: `${extraInfo.filter(Boolean).join('')}${updatedValues.moreInfo || ''}`.trim() });
|
|
106
|
+
delete updatedValues.caseSummaryErrorMessage;
|
|
107
|
+
delete updatedValues.caseSummaryId;
|
|
108
|
+
const emojiRegex = /(\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Extended_Pictographic})+/gu;
|
|
109
|
+
updatedValues.moreInfo = (_a = updatedValues.moreInfo) === null || _a === void 0 ? void 0 : _a.replace(emojiRegex, (match) => encodeURIComponent(match));
|
|
110
|
+
const session = globalThis.sessionjs;
|
|
111
|
+
const userInfo = session.getUserInfo();
|
|
112
|
+
const payload = {
|
|
113
|
+
userName: `${userInfo.firstName} ${userInfo.lastName}`,
|
|
114
|
+
ssoUserName: userInfo.username,
|
|
115
|
+
accountNumber: userInfo.account_number || '',
|
|
116
|
+
userType: session.isInternal() ? 'internal' : 'external',
|
|
117
|
+
foundSolution: '',
|
|
118
|
+
satisfactionLevel: updatedValues.levelOfSatisfied || '',
|
|
119
|
+
savedTime: '',
|
|
120
|
+
feedback: updatedValues.moreInfo || '',
|
|
121
|
+
currentUrl: globalThis.location.href,
|
|
122
|
+
email: userInfo.email || '',
|
|
123
|
+
sessionId: seSessionId || '',
|
|
124
|
+
};
|
|
125
|
+
yield requestPcmFeedback(payload);
|
|
111
126
|
}
|
|
127
|
+
setValues(formInitState); // Reset form state after successful submission
|
|
128
|
+
ToastNotification.addSuccessMessage(t(`Thank you. We've received your feedback.`), t('Have a great day!'));
|
|
129
|
+
handleModalToggle();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
ToastNotification.addDangerMessage(t('Failed to submit feedback.'));
|
|
112
133
|
}
|
|
113
|
-
else
|
|
114
|
-
setIsSubmitDisabled(true);
|
|
115
134
|
});
|
|
116
135
|
// Function for Toggling the Modal when Provide feedback button is clicked
|
|
117
136
|
const handleModalToggle = () => {
|
|
118
137
|
if (isFetching)
|
|
119
138
|
return;
|
|
120
139
|
props.onClose();
|
|
121
|
-
setIsSubmitDisabled(false);
|
|
122
|
-
setValues({ levelOfSatisfied: null, moreInfo: '' });
|
|
123
140
|
};
|
|
124
141
|
// Feedback Satisfaction Values
|
|
125
142
|
const sentiments = [
|
|
@@ -165,13 +182,14 @@ function SupportFeedbackModal(props) {
|
|
|
165
182
|
React.createElement(Icon, { size: "lg" }, sentiment.icon),
|
|
166
183
|
React.createElement(Trans, null, sentiment.label)));
|
|
167
184
|
})),
|
|
168
|
-
|
|
185
|
+
showRatingError && (React.createElement("div", null,
|
|
169
186
|
React.createElement("p", { className: "form-instructions form-invalid" },
|
|
170
187
|
React.createElement(Trans, null, "Please select a value"))))),
|
|
171
|
-
React.createElement(
|
|
172
|
-
React.createElement(
|
|
173
|
-
React.createElement(
|
|
174
|
-
|
|
188
|
+
React.createElement(FormGroup, { label: t('How can we improve?'), isRequired: true, fieldId: "moreFeedback" },
|
|
189
|
+
showFeedbackTextError && (React.createElement(FormHelperText, null,
|
|
190
|
+
React.createElement(HelperText, null,
|
|
191
|
+
React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Please enter your feedback'))))),
|
|
192
|
+
React.createElement(TextArea, { name: "moreInfo", id: "moreFeedback", placeholder: t('i18nDescribeSuggestionDetail', 'Describe your suggestion in detail'), isDisabled: isFetching, value: values.moreInfo, onChange: handleFeedbackTextChange, validated: showFeedbackTextError ? ValidatedOptions.error : ValidatedOptions.default, "aria-label": t('How can we improve?'), resizeOrientation: "vertical", rows: 3 })),
|
|
175
193
|
React.createElement("p", null, props.isCaseSummary ? (React.createElement(Trans, { i18nKey: "Do not share any personal or other sensitive information in your feedback. Feedback may\n be used to improve Red Hat's products or services. For more information about Red Hat\u2019s\n privacy practices, please refer to the <a><u>Red Hat Privacy Statement.</u></a>", components: {
|
|
176
194
|
a: (
|
|
177
195
|
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
|
@@ -187,7 +205,7 @@ function SupportFeedbackModal(props) {
|
|
|
187
205
|
React.createElement("p", { className: "pf-v6-u-mb-sm" }, t('i18nFeedbackFormFoundBug', 'Let us know if you found a bug or if you have a suggestion to improve the web experience.')),
|
|
188
206
|
renderModalBody()),
|
|
189
207
|
React.createElement(ModalFooter, null,
|
|
190
|
-
React.createElement(Button, { key: "confirm", onClick: handleSubmit, variant: "primary", isDisabled:
|
|
208
|
+
React.createElement(Button, { key: "confirm", onClick: handleSubmit, variant: "primary", isDisabled: hasValidationError || isFetching, className: "pf-v6-u-ml-xs", spinnerAriaValueText: isFetching ? 'Loading' : undefined, isLoading: isFetching, "data-tracking-id": "app-feedback-submit", "aria-label": t('Send feedback') },
|
|
191
209
|
React.createElement(Trans, null, isFetching ? 'Sending feedback' : 'Send feedback')),
|
|
192
210
|
React.createElement("button", { key: "cancel", onClick: handleModalToggle, className: "btn btn-app btn-link", "data-tracking-id": "app-feedback-cancel", "aria-label": "Cancel" }, "Cancel")))));
|
|
193
211
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rh-support/components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.10",
|
|
4
4
|
"description": "Contains all reusabel components for support app",
|
|
5
5
|
"author": "Vikas Rathee <vrathee@redhat.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -55,15 +55,15 @@
|
|
|
55
55
|
"use-deep-compare-effect": "^1.6.1"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@cee-eng/hydrajs": "^4.18.
|
|
58
|
+
"@cee-eng/hydrajs": "^4.18.115",
|
|
59
59
|
"@cee-eng/ui-toolkit": "1.1.9",
|
|
60
60
|
"@patternfly/patternfly": "6.2.1",
|
|
61
61
|
"@patternfly/react-core": "6.2.1",
|
|
62
62
|
"@patternfly/react-icons": "6.2.1",
|
|
63
63
|
"@patternfly/react-table": "6.2.1",
|
|
64
64
|
"@rh-support/types": "2.0.26",
|
|
65
|
-
"@rh-support/user-permissions": "2.5.
|
|
66
|
-
"@rh-support/utils": "2.5.
|
|
65
|
+
"@rh-support/user-permissions": "2.5.170",
|
|
66
|
+
"@rh-support/utils": "2.5.149",
|
|
67
67
|
"dompurify": "^2.2.6",
|
|
68
68
|
"js-worker-search": "^1.4.1",
|
|
69
69
|
"lazysizes": "^5.3.2",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"defaults and supports es6-module",
|
|
104
104
|
"maintained node versions"
|
|
105
105
|
],
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "3f16770cee04217483b234f6d8dceaced57a0695"
|
|
107
107
|
}
|