@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":"AAWA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,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;AAMD,iBAAS,oBAAoB,CAAC,KAAK,EAAE,MAAM,qBA0R1C;kBA1RQ,oBAAoB;;;AA6R7B,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
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
- const required = {
26
- levelOfSatisfied: true,
27
- moreInfo: false,
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: requestFeedbackForm, isFetching: isFetchingFeedback } = useFetch(pcm.sendFeedbackForm, {
46
+ const { request: requestPcmFeedback, isFetching: isFetchingFeedback } = useFetch(pcm.submitPcmFeedback, {
46
47
  propgateErrors: true,
47
48
  });
48
49
  const isFetching = isFetchingAISummary || isFetchingFeedback;
49
- const [isSubmitDisabled, setIsSubmitDisabled] = useState(false);
50
- const [isSubmitButtonValid, setSubmitButtonValid] = useState(true);
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
- let valid = true;
53
- Object.keys(values).forEach((key) => {
54
- if (required[key]) {
55
- valid = valid && !isEmpty(values[key]);
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
- setIsSubmitDisabled(false);
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 = (event) => {
75
- setValues(Object.assign(Object.assign({}, values), { [event.target.name]: event.target.value }));
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
- if (!isSubmitButtonValid) {
82
- let updatedValues = Object.assign({}, values);
83
- try {
84
- if (props.isCaseSummary) {
85
- const aiPayload = {
86
- caseNumber: caseNumber || '',
87
- feedback: values.levelOfSatisfied || '',
88
- description: values.moreInfo || '',
89
- };
90
- yield requestAISummary(aiPayload, window.sessionjs);
91
- }
92
- else {
93
- const extraInfo = [
94
- props.errorMessage && `caseSummaryErrorMessage:'${props.errorMessage}'\n`,
95
- props.caseSummaryId && `caseSummaryId:'${props.caseSummaryId}'\n`,
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
- catch (error) {
110
- ToastNotification.addDangerMessage(t('Failed to submit feedback.'));
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
- isSubmitDisabled && (React.createElement("div", null,
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("div", { className: "form-group pf-v6-u-mb-md" },
172
- React.createElement("label", { htmlFor: "moreFeedback" },
173
- React.createElement(Trans, null, "How can we improve?")),
174
- React.createElement(TextAreaAutosize, { name: "moreInfo", id: "moreFeedback", placeholder: t('i18nDescribeSuggestionDetail', 'Describe your suggestion in detail'), disabled: isFetching, value: values.moreInfo, className: "form-control", onChange: handleFeedbackTextChange, rowsMin: 3 })),
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: isSubmitDisabled || isFetching, className: "pf-v6-u-ml-xs", spinnerAriaValueText: isFetching ? 'Loading' : undefined, isLoading: isFetching, "data-tracking-id": "app-feedback-submit", "aria-label": t('Send feedback') },
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.5.230",
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.114",
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.178",
66
- "@rh-support/utils": "2.5.157",
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": "78790ed8b35b8acbc7a3a4a182d212499a0cd181"
106
+ "gitHead": "3f16770cee04217483b234f6d8dceaced57a0695"
107
107
  }