@rh-support/troubleshoot 2.6.90 → 2.6.93

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 (46) hide show
  1. package/lib/esm/components/AccountInfo/OwnerSelector.d.ts.map +1 -1
  2. package/lib/esm/components/AccountInfo/OwnerSelector.js +1 -0
  3. package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.d.ts.map +1 -1
  4. package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.js +51 -406
  5. package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
  6. package/lib/esm/components/CaseEditView/Case.js +3 -2
  7. package/lib/esm/components/CaseEditView/CaseDetailsErrorMessage.d.ts +1 -0
  8. package/lib/esm/components/CaseEditView/CaseDetailsErrorMessage.d.ts.map +1 -1
  9. package/lib/esm/components/CaseEditView/CaseDetailsErrorMessage.js +3 -3
  10. package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutions.d.ts.map +1 -1
  11. package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutions.js +18 -2
  12. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseOpenshiftClusterId/CaseOpenshiftClusterId.d.ts.map +1 -1
  13. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseOpenshiftClusterId/CaseOpenshiftClusterId.js +7 -4
  14. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.d.ts.map +1 -1
  15. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.js +14 -2
  16. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.d.ts.map +1 -1
  17. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.js +6 -0
  18. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.d.ts.map +1 -1
  19. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.js +0 -1
  20. package/lib/esm/components/CaseInformation/SupportLevel.d.ts.map +1 -1
  21. package/lib/esm/components/CaseInformation/SupportLevel.js +6 -1
  22. package/lib/esm/components/CaseManagement/NoClusterIDReasonSelector.d.ts.map +1 -1
  23. package/lib/esm/components/CaseManagement/NoClusterIDReasonSelector.js +20 -12
  24. package/lib/esm/components/CaseManagement/OpenShiftClusterId.d.ts.map +1 -1
  25. package/lib/esm/components/CaseManagement/OpenShiftClusterId.js +7 -2
  26. package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.d.ts +1 -0
  27. package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.d.ts.map +1 -1
  28. package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.js +10 -6
  29. package/lib/esm/components/TroubleshootSection/AskRedHat.d.ts.map +1 -1
  30. package/lib/esm/components/shared/useIsSectionValid.d.ts.map +1 -1
  31. package/lib/esm/components/shared/useIsSectionValid.js +7 -8
  32. package/lib/esm/components/wizardLayout/WizardNavigation.d.ts.map +1 -1
  33. package/lib/esm/components/wizardLayout/WizardNavigation.js +8 -4
  34. package/lib/esm/reducers/CaseConstNTypes.d.ts +1 -13
  35. package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
  36. package/lib/esm/reducers/CaseConstNTypes.js +0 -12
  37. package/lib/esm/reducers/CaseHelpers.d.ts.map +1 -1
  38. package/lib/esm/reducers/CaseHelpers.js +2 -1
  39. package/lib/esm/reducers/CaseReducer.d.ts +1 -0
  40. package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
  41. package/lib/esm/reducers/CaseReducer.js +1 -1
  42. package/lib/esm/reducers/RouteReducer.d.ts +2 -2
  43. package/lib/esm/reducers/RouteReducer.d.ts.map +1 -1
  44. package/lib/esm/reducers/RouteReducer.js +1 -1
  45. package/lib/esm/scss/_pf-overrides.scss +31 -202
  46. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"OwnerSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/AccountInfo/OwnerSelector.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAiBxE,UAAU,MAAM;CAAG;AAMnB,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,qBAqSnC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"OwnerSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/AccountInfo/OwnerSelector.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAiBxE,UAAU,MAAM;CAAG;AAMnB,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,qBAsSnC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -120,6 +120,7 @@ function OwnerSelector(props) {
120
120
  firstName: newOwner.firstName,
121
121
  lastName: newOwner.lastName,
122
122
  fullNameCustom: newOwner.fullNameCustom,
123
+ manageSupportCases: newOwner.manageSupportCases,
123
124
  }, '', abortSignal, abortSignal, false, '', true, true, caseNumber);
124
125
  setLocalOwnerChange(true);
125
126
  updateNotifyUsersList(newOwner);
@@ -1 +1 @@
1
- {"version":3,"file":"RequestEscalationModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAuBnD,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAID,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,qBAy+BnD"}
1
+ {"version":3,"file":"RequestEscalationModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAkBnD,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAID,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,qBA6WnD"}
@@ -8,8 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { escalations, publicApi } from '@cee-eng/hydrajs';
11
- import { Button, Form, FormGroup, FormHelperText, Grid, GridItem, HelperText, HelperTextItem, Modal, ModalBody, ModalHeader, ModalVariant, Radio, TextArea, TextInput, TimePicker, Title, ValidatedOptions, Wizard, WizardNav, WizardNavItem, WizardStep, } from '@patternfly/react-core';
12
- import { AlertMessage, AlertType, COUNTRY_DATA, getPhoneObj, PhoneInput, SingleSelectDropdown, ToastNotification, useFetch, } from '@rh-support/components';
11
+ import { Button, Form, FormGroup, FormHelperText, Grid, GridItem, HelperText, HelperTextItem, Modal, ModalBody, ModalFooter, ModalHeader, Popover, TextArea, TextInput, Title, ValidatedOptions, } from '@patternfly/react-core';
12
+ import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
13
+ import { AlertMessage, AlertType, LoadingIndicator, SingleSelectDropdown, ToastNotification, useFetch, } from '@rh-support/components';
13
14
  import { useGlobalStateContext } from '@rh-support/react-context';
14
15
  import isEmpty from 'lodash/isEmpty';
15
16
  import React, { useEffect, useState } from 'react';
@@ -18,14 +19,12 @@ import { useCaseDispatch } from '../../../context/CaseContext';
18
19
  import { useCaseDetailsPageDispatchContext, useCaseDetailsPageStateContext, } from '../../../context/CaseDetailsPageContext';
19
20
  import { useCaseDiscussionTabDispatchContext, useCaseDiscussionTabStateContext, } from '../../../context/CaseDiscussionTabContext';
20
21
  import { CustomerGEOs } from '../../../enums/customerGEOs';
21
- import { ESCALATION_SUBJECT_LENGTH_LIMIT, PHONE_LIMIT, TIMEZONE_OPTIONS, } from '../../../reducers/CaseConstNTypes';
22
+ import { ESCALATION_SUBJECT_LENGTH_LIMIT } from '../../../reducers/CaseConstNTypes';
22
23
  import { fetchCaseEscalations } from '../../../reducers/CaseDetailsPageReducer';
23
24
  import { updateDiscussionStateComments } from '../../../reducers/CaseDiscussionTabReducer';
24
25
  import { checkForCaseStatusToggleOnAttachOrComment, fetchCaseDetails } from '../../../reducers/CaseReducer';
25
- import { removeAllChars, trimAndReplacePlus } from '../../shared/utils';
26
26
  const customerGEOKeys = Object.keys(CustomerGEOs);
27
27
  export function RequestEscalationModal(props) {
28
- var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
29
28
  const { globalMetadataState: { loggedInUser, loggedInUserRights }, } = useGlobalStateContext();
30
29
  const { t } = useTranslation();
31
30
  const [categories, setCategories] = useState([]);
@@ -36,101 +35,12 @@ export function RequestEscalationModal(props) {
36
35
  geo: '',
37
36
  businessImpactDescription: '',
38
37
  rmeCategory: '',
39
- contactName: '',
40
- contactTitle: '',
41
- contactPreference: '',
42
- countryCode: '',
43
- phoneNumber: '',
44
- timezone: '',
45
- preferredTimeFrom: '',
46
- preferredTimeTo: '',
47
38
  };
48
39
  const [formState, setFormState] = useState(initialState);
49
40
  const [hasLargeSubject, setHasLargeSubject] = useState(false);
50
41
  const [submitButtonIsClicked, setSubmitSaveButtonIsClicked] = useState(false);
51
- const [isPhoneInvalid, setIsPhoneInvalid] = useState(false);
52
- const isCountryCodeValid = (countryCode) => {
53
- // Check if the country code exists in the valid country codes list
54
- if (!countryCode)
55
- return false;
56
- const normalizedCode = trimAndReplacePlus(countryCode);
57
- if (isEmpty(normalizedCode))
58
- return false;
59
- return COUNTRY_DATA.some((country) => country[3] === normalizedCode);
60
- };
61
- const isPhoneNumberInvalid = (phoneNumber, countryCode) => {
62
- var _a;
63
- // Check if country code is given but phone number is empty/only has country code
64
- return (!isEmpty(phoneNumber) &&
65
- isEmpty((_a = removeAllChars(phoneNumber || '')) === null || _a === void 0 ? void 0 : _a.replace(trimAndReplacePlus(countryCode || ''), '')));
66
- };
67
- const isPhoneLineEmpty = (phoneNumber, countryCode) => {
68
- var _a;
69
- // Check if both country code and phone line are empty
70
- return (isEmpty(trimAndReplacePlus(countryCode || '')) &&
71
- isEmpty((_a = (phoneNumber || '')) === null || _a === void 0 ? void 0 : _a.replace(countryCode || '', '')));
72
- };
73
- const isPhoneNumberValid = (phoneNumber, countryCode) => {
74
- const trimmedPhone = (phoneNumber || '').trim();
75
- const phoneObject = getPhoneObj(trimmedPhone);
76
- const fullPhone = phoneObject.countryCode + ' ' + phoneObject.phoneLine;
77
- // Check for various invalid states
78
- if (fullPhone.length > PHONE_LIMIT)
79
- return false;
80
- if (isPhoneLineEmpty(phoneNumber, countryCode))
81
- return false;
82
- if (isPhoneNumberInvalid(phoneNumber, countryCode))
83
- return false;
84
- if (isEmpty(trimAndReplacePlus(countryCode || '')))
85
- return false;
86
- if (!isCountryCodeValid(countryCode))
87
- return false;
88
- if (trimAndReplacePlus(trimmedPhone) === trimAndReplacePlus(countryCode || ''))
89
- return false;
90
- if (trimmedPhone.length < 5)
91
- return false;
92
- return true;
93
- };
94
- // Function to check if "to" time is after "from" time
95
- const isValidTimeRange = (fromTime, toTime) => {
96
- if (!fromTime || !toTime)
97
- return true; // Don't validate if either is empty
98
- // Convert time strings to comparable numbers (HH:MM -> HHMM)
99
- const fromMinutes = fromTime.split(':').map(Number);
100
- const toMinutes = toTime.split(':').map(Number);
101
- if (fromMinutes.length !== 2 || toMinutes.length !== 2)
102
- return true;
103
- const fromTotal = fromMinutes[0] * 60 + fromMinutes[1];
104
- const toTotal = toMinutes[0] * 60 + toMinutes[1];
105
- return toTotal > fromTotal;
106
- };
107
42
  // checks if all the fields have values.
108
- const hasRequiredInfo = () => {
109
- const requiredFields = [
110
- 'subject',
111
- 'description',
112
- 'expectations',
113
- 'geo',
114
- 'businessImpactDescription',
115
- 'rmeCategory',
116
- 'contactName',
117
- 'contactTitle',
118
- 'contactPreference',
119
- ];
120
- if (formState.contactPreference === 'call-me' || formState.contactPreference === 'call-if-necessary') {
121
- requiredFields.push('phoneNumber', 'timezone', 'preferredTimeFrom', 'preferredTimeTo');
122
- }
123
- const hasAllFields = requiredFields.every((field) => formState[field] && formState[field].toString().trim().length > 0);
124
- if ((formState.contactPreference === 'call-me' || formState.contactPreference === 'call-if-necessary') &&
125
- formState.preferredTimeFrom &&
126
- formState.preferredTimeTo) {
127
- return (hasAllFields &&
128
- isValidTimeRange(formState.preferredTimeFrom, formState.preferredTimeTo) &&
129
- !isPhoneInvalid &&
130
- isPhoneNumberValid(formState.phoneNumber, formState.countryCode));
131
- }
132
- return hasAllFields;
133
- };
43
+ const hasRequiredInfo = () => Object.keys(formState).reduce((accumulator, currentValue) => { var _a; return !accumulator ? accumulator : formState[currentValue].length > 0 && ((_a = formState[currentValue]) === null || _a === void 0 ? void 0 : _a.trim()); }, true);
134
44
  const setFormStateValue = (key, value) => setFormState((pre) => (Object.assign(Object.assign({}, pre), { [key]: value })));
135
45
  const createEscalationFetch = useFetch(escalations.createIceEscalation, { propgateErrors: true });
136
46
  const { request: postCommentRequest, isFetching: isPostingComment } = useFetch(publicApi.kase.postComment, {
@@ -173,7 +83,6 @@ export function RequestEscalationModal(props) {
173
83
  setSubmitSaveButtonIsClicked(false);
174
84
  setFormState(initialState);
175
85
  setHasLargeSubject(false);
176
- setIsPhoneInvalid(false);
177
86
  props.onClose();
178
87
  };
179
88
  const onSubmit = () => __awaiter(this, void 0, void 0, function* () {
@@ -181,72 +90,14 @@ export function RequestEscalationModal(props) {
181
90
  if (!hasRequiredInfo() || hasLargeSubject)
182
91
  return;
183
92
  try {
184
- let contactDetailsString = '\n\n--- Contact Details ---';
185
- contactDetailsString += `\nName: ${formState.contactName}`;
186
- contactDetailsString += `\nTitle: ${formState.contactTitle}`;
187
- const contactPrefMap = {
188
- 'call-me': 'Call me',
189
- 'call-if-necessary': 'Call only if necessary',
190
- 'do-not-call': 'Do not call',
191
- };
192
- contactDetailsString += `\nContact Preference: ${formState.contactPreference
193
- ? contactPrefMap[formState.contactPreference] || formState.contactPreference
194
- : ''}`;
195
- if (formState.contactPreference === 'call-me' || formState.contactPreference === 'call-if-necessary') {
196
- contactDetailsString += `\nPhone Number: ${formState.phoneNumber}`;
197
- contactDetailsString += `\nTimezone: ${formState.timezone}`;
198
- contactDetailsString += `\nPreferred Time to Call: ${formState.preferredTimeFrom} to ${formState.preferredTimeTo}`;
199
- }
200
- const enhancedDescription = formState.description + contactDetailsString;
201
- // Use contact phone if provided, otherwise use logged in user's phone
202
- const requestorPhone = (formState.contactPreference === 'call-me' || formState.contactPreference === 'call-if-necessary') &&
203
- formState.phoneNumber
204
- ? formState.phoneNumber
205
- : loggedInUser.data.phone;
206
- const res = yield createEscalationFetch.request({
207
- subject: formState.subject,
208
- description: enhancedDescription,
209
- expectations: formState.expectations,
210
- geo: formState.geo,
211
- businessImpactDescription: formState.businessImpactDescription,
212
- rmeCategory: formState.rmeCategory,
213
- recordType: 'Active Customer Escalation',
214
- escalationSource: 'RME Escalation',
215
- status: 'New',
216
- accountNumber: loggedInUserRights.data.getAccountNumber(),
217
- caseNumber: props.caseNumber,
218
- requestor: formState.contactName || `${loggedInUser.data.firstName} ${loggedInUser.data.lastName}`,
219
- requestorEmail: loggedInUser.data.email,
220
- requestorPhone: requestorPhone,
221
- alreadyEscalated: false,
222
- severity: props.severity ? props.severity.charAt(0) : '3',
223
- });
224
- const formattedContactPreference = formState.contactPreference
225
- ? contactPrefMap[formState.contactPreference] || formState.contactPreference
226
- : '';
227
- // Format time to 12-hour format
228
- const formatTime = (time24) => {
229
- if (!time24)
230
- return '';
231
- const [hours, minutes] = time24.split(':');
232
- const hour = parseInt(hours);
233
- const ampm = hour >= 12 ? 'pm' : 'am';
234
- const hour12 = hour % 12 || 12;
235
- return `${hour12}:${minutes}${ampm}`;
236
- };
237
- const fullComment = t('### Request Management Escalation:\n\n**Name**\n{{contactName}}\n\n**Title**\n{{contactTitle}}\n\n**Subject**\n{{subject}}\n\n**Category**\n{{rmeCategory}}\n\n**Description**\n{{description}}\n\n**Expectations**\n{{expectations}}\n\n**Business impact**\n{{businessImpactDescription}}\n\n**Contact preference**\n{{contactPreference}}{{phoneDetails}}\n\n', {
93
+ const res = yield createEscalationFetch.request(Object.assign(Object.assign({}, formState), { recordType: 'Active Customer Escalation', escalationSource: 'RME Escalation', status: 'New', accountNumber: loggedInUserRights.data.getAccountNumber(), caseNumber: props.caseNumber, requestor: `${loggedInUser.data.firstName} ${loggedInUser.data.lastName}`, requestorEmail: loggedInUser.data.email, requestorPhone: loggedInUser.data.phone, alreadyEscalated: false, severity: props.severity ? props.severity.charAt(0) : '3' }));
94
+ const fullComment = t('### Request Management Escalation:\n\n**Subject**\n{{subject}}\n\n**Category**\n{{rmeCategory}}\n\n**Description**\n{{description}}\n\n**Expectations**\n{{expectations}}\n\n**Business Impact**\n{{businessImpactDescription}}', {
238
95
  category: formState.rmeCategory,
239
96
  subject: formState.subject,
240
97
  description: formState.description,
241
98
  expectations: formState.expectations,
242
99
  businessImpactDescription: formState.businessImpactDescription,
243
100
  rmeCategory: formState.rmeCategory,
244
- contactName: formState.contactName || 'Not provided',
245
- contactTitle: formState.contactTitle || 'Not provided',
246
- contactPreference: formattedContactPreference || 'Not provided',
247
- phoneDetails: formState.contactPreference === 'call-me' || formState.contactPreference === 'call-if-necessary'
248
- ? `\n\n**Case owner's phone number**\n${formState.phoneNumber}\nNote: Phone number will be stored in case comments for escalation only – not used for marketing.\n\n**Timezone**\n${formState.timezone}\n\n**Best time to connect regarding escalation**\nFrom ${formatTime(formState.preferredTimeFrom || '')} to ${formatTime(formState.preferredTimeTo || '')}`
249
- : '',
250
101
  });
251
102
  try {
252
103
  yield submitEscalationComment(res.name, fullComment);
@@ -254,12 +105,6 @@ export function RequestEscalationModal(props) {
254
105
  catch (e) {
255
106
  // silently fails, escalation is created but adding comment fails
256
107
  }
257
- // Reset form state before closing
258
- setFormState(initialState);
259
- setSubmitSaveButtonIsClicked(false);
260
- setHasLargeSubject(false);
261
- setIsPhoneInvalid(false);
262
- setCreationError(false);
263
108
  props.onClose();
264
109
  }
265
110
  catch (error) {
@@ -267,6 +112,11 @@ export function RequestEscalationModal(props) {
267
112
  setCreationError(true);
268
113
  }
269
114
  });
115
+ const header = (React.createElement(Title, { className: "pf-v6-u-mb-0", id: "custom-header-label", headingLevel: "h1" },
116
+ React.createElement(Trans, null, "Request an escalation"),
117
+ React.createElement(Popover, { showClose: false, position: 'top', hasAutoWidth: true, bodyContent: () => (React.createElement("a", { href: "/support/escalation", target: "_blank", "aria-label": t('Learn more about escalation cases.') },
118
+ React.createElement(Trans, null, "Learn more about escalation cases."))) },
119
+ React.createElement(InfoCircleIcon, { className: "pf-v6-u-ml-sm" }))));
270
120
  // load rme categories as soon as user opens the modal
271
121
  useEffect(() => {
272
122
  if (!props.show || categories.length !== 0)
@@ -274,7 +124,7 @@ export function RequestEscalationModal(props) {
274
124
  const fetchCategories = () => __awaiter(this, void 0, void 0, function* () {
275
125
  try {
276
126
  const categories = yield getRmeCategories();
277
- setCategories(((categories === null || categories === void 0 ? void 0 : categories.items) || []));
127
+ setCategories((categories === null || categories === void 0 ? void 0 : categories.items) || []);
278
128
  }
279
129
  catch (e) {
280
130
  console.log(e);
@@ -305,251 +155,46 @@ export function RequestEscalationModal(props) {
305
155
  value: formState.geo,
306
156
  label: findSelectedGeoLabel() || t('Select a location'),
307
157
  };
308
- // Create custom footer function for wizard
309
- const CustomFooter = (activeStep, goToNextStep, goToPrevStep) => {
310
- const isLastStep = activeStep.id === 'contact-details';
311
- const isFirstStep = activeStep.id === 'escalation-details';
312
- const isLoading = isPostingComment || isUpdatingCase || createEscalationFetch.isFetching;
313
- // Validate current step
314
- const isCurrentStepValid = () => {
315
- if (activeStep.id === 'escalation-details') {
316
- return ((formState.rmeCategory || '').trim().length > 0 &&
317
- (formState.geo || '').trim().length > 0 &&
318
- (formState.subject || '').trim().length > 0 &&
319
- !hasLargeSubject &&
320
- (formState.description || '').trim().length > 0 &&
321
- (formState.expectations || '').trim().length > 0 &&
322
- (formState.businessImpactDescription || '').trim().length > 0);
323
- }
324
- else if (activeStep.id === 'contact-details') {
325
- const baseValidation = (formState.contactName || '').trim().length > 0 &&
326
- (formState.contactTitle || '').trim().length > 0 &&
327
- (formState.contactPreference || '').trim().length > 0;
328
- // Additional validation if call options are selected
329
- if (formState.contactPreference === 'call-me' || formState.contactPreference === 'call-if-necessary') {
330
- return (baseValidation &&
331
- isPhoneNumberValid(formState.phoneNumber, formState.countryCode) &&
332
- !isPhoneInvalid &&
333
- (formState.preferredTimeFrom || '').trim().length > 0 &&
334
- (formState.preferredTimeTo || '').trim().length > 0 &&
335
- (formState.timezone || '').trim().length > 0);
336
- }
337
- return baseValidation;
338
- }
339
- return false;
340
- };
341
- const handleNext = () => {
342
- setSubmitSaveButtonIsClicked(true);
343
- if (isCurrentStepValid()) {
344
- setSubmitSaveButtonIsClicked(false); // Reset validation state when moving to next step
345
- goToNextStep({});
346
- }
347
- };
348
- const handleSubmit = () => {
349
- setSubmitSaveButtonIsClicked(true);
350
- if (isCurrentStepValid()) {
351
- onSubmit();
352
- }
353
- };
354
- return (React.createElement("div", { className: "pf-v6-c-wizard__footer" },
355
- !isFirstStep && (React.createElement(Button, { variant: "secondary", onClick: () => {
356
- setSubmitSaveButtonIsClicked(false);
357
- goToPrevStep({});
358
- }, isDisabled: isLoading, "data-tracking-id": "request-rme-back" }, t('Back'))),
359
- React.createElement(Button, { variant: "primary", onClick: isLastStep ? handleSubmit : handleNext, isDisabled: isLoading || (submitButtonIsClicked && !isCurrentStepValid()), isLoading: isLoading, "data-tracking-id": isLastStep ? 'request-rme-submit' : 'request-rme-next' }, isLastStep ? t('Submit') : t('Next')),
360
- React.createElement(Button, { variant: "link", onClick: onCancel, isDisabled: isLoading, "data-tracking-id": "request-rme-cancel" }, t('Cancel'))));
361
- };
362
- const escalationDetailsStep = (React.createElement(WizardStep, { id: "escalation-details", name: t('Escalation details') },
363
- React.createElement("div", { className: "wizard-step-content" },
364
- React.createElement(Title, { headingLevel: "h2", size: "2xl", className: "pf-v6-u-mb-lg" }, t('Escalation details')),
365
- React.createElement(Form, { "aria-label": t('Escalation details form'), className: "request-escalation-form" },
366
- React.createElement(Grid, { hasGutter: true },
158
+ return (React.createElement(Modal, { id: "request-mgmt-escalation-modal", className: "request-escalation-modal", isOpen: props.show, onClose: onCancel, "aria-label": t('Request an escalation') },
159
+ React.createElement(ModalHeader, null, header),
160
+ React.createElement(ModalBody, null,
161
+ React.createElement("p", { className: "pf-v6-u-mb-md" },
162
+ React.createElement(Trans, { i18nKey: "i18RequestEscalationDescription" }, "Submit an escalation if an issue has become more severe or you feel the case needs a higher priority. A support manager will review your escalation request.")),
163
+ React.createElement(AlertMessage, { variant: AlertType.DANGER, title: t('Could not create case escalation'), show: creationError, onClose: onErrorClose, isInline: true, className: "pf-v6-u-mb-md", "aria-label": t('Could not create case escalation') }),
164
+ React.createElement(Form, { "aria-label": t('form'), className: "request-escalation-form" },
165
+ React.createElement(Grid, { hasGutter: true, md: 12 },
367
166
  React.createElement(GridItem, { span: 6 },
368
167
  React.createElement(FormGroup, { isRequired: true, label: t('Category'), fieldId: "escalation-category" },
369
- React.createElement(SingleSelectDropdown, { id: "customer-category-select", ariaLabel: t('Category'), selected: selectedCategory, options: categoryOptions, isDisabled: false, isLoading: isCategoriesFetching, isInvalid: submitButtonIsClicked && !((_a = formState.rmeCategory) === null || _a === void 0 ? void 0 : _a.trim()), placeholder: t('Select an option that best fits'), onSelect: (option) => setCategoryState(option), isScrollable: true }))),
168
+ React.createElement(SingleSelectDropdown, { id: "customer-category-select", ariaLabel: t('Category'), selected: selectedCategory, options: categoryOptions, isDisabled: false, isLoading: isCategoriesFetching, isInvalid: submitButtonIsClicked && isEmpty(formState.rmeCategory), placeholder: t('Select an option that best fits'), onSelect: (option) => setCategoryState(option), isScrollable: true }))),
370
169
  React.createElement(GridItem, { span: 6 },
371
170
  React.createElement(FormGroup, { isRequired: true, label: t('My region'), fieldId: "escalation-region" },
372
- React.createElement(SingleSelectDropdown, { ariaLabel: t('My region'), id: "customer-geo-select", selected: selectedGeo, options: geoOptions, isInvalid: submitButtonIsClicked && !((_b = formState.geo) === null || _b === void 0 ? void 0 : _b.trim()), placeholder: t('Select a location'), onSelect: (option) => setGeoState(option) }))),
373
- React.createElement(GridItem, { span: 12 },
374
- React.createElement(FormGroup, { isRequired: true, label: t('Subject'), fieldId: "escalation-subject" },
375
- submitButtonIsClicked && hasLargeSubject && (React.createElement(FormHelperText, null,
376
- React.createElement(HelperText, null,
377
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Subject cannot be more than {{limit}} characters', {
378
- limit: ESCALATION_SUBJECT_LENGTH_LIMIT,
379
- }))))),
380
- React.createElement(TextInput, { isRequired: true, validated: (submitButtonIsClicked && !((_c = formState.subject) === null || _c === void 0 ? void 0 : _c.trim())) || hasLargeSubject
381
- ? ValidatedOptions.error
382
- : ValidatedOptions.default, type: "text", placeholder: t('Enter a subject for your request'), id: "subject-input", name: "subject-input", value: formState.subject, onChange: (_event, subject) => onSubjectChange(subject), "aria-label": t('Subject') }))),
383
- React.createElement(GridItem, { span: 12 },
384
- React.createElement(FormGroup, { isRequired: true, label: t('Description'), fieldId: "escalation-description" },
385
- React.createElement(TextArea, { value: formState.description, onChange: (e, value) => setFormStateValue('description', value), isRequired: true, validated: submitButtonIsClicked && !((_d = formState.description) === null || _d === void 0 ? void 0 : _d.trim())
386
- ? ValidatedOptions.error
387
- : ValidatedOptions.default, "aria-label": t('Description'), id: "description-textarea", placeholder: t('Provide a detailed comment for us to best assist you'), resizeOrientation: "vertical" }))),
388
- React.createElement(GridItem, { span: 12 },
389
- React.createElement(FormGroup, { isRequired: true, label: t('Expectations'), fieldId: "escalation-expectations" },
390
- React.createElement(TextArea, { onChange: (e, value) => setFormStateValue('expectations', value), isRequired: true, validated: submitButtonIsClicked && !((_f = formState.expectations) === null || _f === void 0 ? void 0 : _f.trim())
391
- ? ValidatedOptions.error
392
- : ValidatedOptions.default, placeholder: t('What do you expect to happen with this escalation?'), id: "expectations-input", value: formState.expectations, "aria-label": t('Expectations'), resizeOrientation: "vertical" }))),
393
- React.createElement(GridItem, { span: 12 },
394
- React.createElement(FormGroup, { isRequired: true, label: t('Business impact'), fieldId: "escalation-business-impact" },
395
- React.createElement(TextArea, { onChange: (e, value) => setFormStateValue('businessImpactDescription', value), isRequired: true, validated: submitButtonIsClicked && !((_g = formState.businessImpactDescription) === null || _g === void 0 ? void 0 : _g.trim())
396
- ? ValidatedOptions.error
397
- : ValidatedOptions.default, placeholder: t('Does your business impact change with this escalation? Please describe how it changed.'), id: "business-impact-input", value: formState.businessImpactDescription, "aria-label": t('Business impact'), resizeOrientation: "vertical" }))))))));
398
- // Check if first step is completed
399
- const isFirstStepComplete = () => {
400
- return ((formState.rmeCategory || '').trim().length > 0 &&
401
- (formState.geo || '').trim().length > 0 &&
402
- (formState.subject || '').trim().length > 0 &&
403
- !hasLargeSubject &&
404
- (formState.description || '').trim().length > 0 &&
405
- (formState.expectations || '').trim().length > 0 &&
406
- (formState.businessImpactDescription || '').trim().length > 0);
407
- };
408
- const customNav = (isExpanded, steps, activeStep, goToStepByIndex) => (React.createElement(WizardNav, { isExpanded: isExpanded }, steps.map((step, index) => {
409
- // Disable the second step if first step is not complete
410
- const isDisabled = step.id === 'contact-details' && !isFirstStepComplete();
411
- return (React.createElement(WizardNavItem, { key: step.id, id: step.id, content: step.name, isCurrent: activeStep.id === step.id, isDisabled: isDisabled, stepIndex: step.index, onClick: () => !isDisabled && goToStepByIndex(step.index) }));
412
- })));
413
- const contactDetailsStep = (React.createElement(WizardStep, { id: "contact-details", name: t('Contact details') },
414
- React.createElement("div", { className: "wizard-step-content" },
415
- React.createElement(Title, { headingLevel: "h2", size: "2xl", className: "pf-v6-u-mb-lg" }, t('Contact details')),
416
- React.createElement(Form, { "aria-label": t('Contact details form'), className: "request-escalation-form" },
417
- React.createElement(Grid, { hasGutter: true },
418
- React.createElement(GridItem, { span: 6 },
419
- React.createElement(FormGroup, { label: React.createElement(React.Fragment, null,
420
- t('Name'),
421
- " "), isRequired: true, fieldId: "contact-name" },
422
- React.createElement(TextInput, { type: "text", validated: submitButtonIsClicked && !((_h = formState.contactName) === null || _h === void 0 ? void 0 : _h.trim())
423
- ? ValidatedOptions.error
424
- : ValidatedOptions.default, placeholder: t('Enter your name'), id: "contact-name", value: formState.contactName || '', onChange: (_e, value) => setFormState(Object.assign(Object.assign({}, formState), { contactName: value })), "aria-label": t('Contact name') }),
425
- submitButtonIsClicked && !((_j = formState.contactName) === null || _j === void 0 ? void 0 : _j.trim()) && (React.createElement(FormHelperText, null,
426
- React.createElement(HelperText, null,
427
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Name is required'))))))),
428
- React.createElement(GridItem, { span: 6 },
429
- React.createElement(FormGroup, { label: React.createElement(React.Fragment, null,
430
- t('Title'),
431
- " "), isRequired: true, fieldId: "contact-title" },
432
- React.createElement(TextInput, { type: "text", validated: submitButtonIsClicked && !((_k = formState.contactTitle) === null || _k === void 0 ? void 0 : _k.trim())
433
- ? ValidatedOptions.error
434
- : ValidatedOptions.default, placeholder: t('Enter your title (e.g. System Admin, DevOps, Project Man..)'), id: "contact-title", value: formState.contactTitle || '', onChange: (_e, value) => setFormState(Object.assign(Object.assign({}, formState), { contactTitle: value })), "aria-label": t('Contact title') }),
435
- submitButtonIsClicked && !((_l = formState.contactTitle) === null || _l === void 0 ? void 0 : _l.trim()) && (React.createElement(FormHelperText, null,
436
- React.createElement(HelperText, null,
437
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Title is required'))))))),
438
- React.createElement(GridItem, { span: 12 },
439
- React.createElement(FormGroup, { label: React.createElement(React.Fragment, null,
440
- t('Contact preference'),
441
- " "), isRequired: true, fieldId: "contact-preference", role: "radiogroup" },
442
- React.createElement("div", { className: "pf-v6-u-display-flex pf-v6-u-flex-direction-row contact-preference-group" },
443
- React.createElement(Radio, { id: "call-me", name: "contact-preference", label: t('Call me'), isChecked: formState.contactPreference === 'call-me', onChange: () => setFormState(Object.assign(Object.assign({}, formState), { contactPreference: 'call-me' })), style: { marginRight: '24px' } }),
444
- React.createElement(Radio, { id: "call-if-necessary", name: "contact-preference", label: t('Call only if necessary'), isChecked: formState.contactPreference === 'call-if-necessary', onChange: () => setFormState(Object.assign(Object.assign({}, formState), { contactPreference: 'call-if-necessary' })), style: { marginRight: '8px' } }),
445
- React.createElement(Radio, { id: "do-not-call", name: "contact-preference", label: t('Do not call'), isChecked: formState.contactPreference === 'do-not-call', onChange: () => setFormState(Object.assign(Object.assign({}, formState), { contactPreference: 'do-not-call', phoneNumber: '', timezone: '', preferredTimeFrom: '', preferredTimeTo: '' })) })),
446
- submitButtonIsClicked && !formState.contactPreference && (React.createElement(FormHelperText, null,
447
- React.createElement(HelperText, null,
448
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Contact preference is required'))))))),
449
- (formState.contactPreference === 'call-me' ||
450
- formState.contactPreference === 'call-if-necessary') && (React.createElement(React.Fragment, null,
451
- React.createElement(GridItem, { span: 12 },
452
- React.createElement(FormGroup, { label: React.createElement(React.Fragment, null,
453
- t("Case owner's phone number"),
454
- " "), isRequired: true, fieldId: "phone-number" },
455
- React.createElement(PhoneInput, { phoneValue: formState.phoneNumber || '', countryCode: ((_m = formState.countryCode) === null || _m === void 0 ? void 0 : _m.replace('+', '')) || '', onPhoneValueChange: (phone) => setFormState(Object.assign(Object.assign({}, formState), { phoneNumber: phone })), onCountryCodeChange: (code) => setFormState(Object.assign(Object.assign({}, formState), { countryCode: code })), validations: (submitButtonIsClicked &&
456
- !isPhoneNumberValid(formState.phoneNumber, formState.countryCode)) ||
457
- isPhoneInvalid ||
458
- (submitButtonIsClicked &&
459
- (getPhoneObj(formState.phoneNumber || '').countryCode +
460
- ' ' +
461
- getPhoneObj(formState.phoneNumber || '').phoneLine).length > PHONE_LIMIT)
462
- ? 'error'
463
- : 'default', isDisabled: false, invalid: isPhoneInvalid, setInvalid: setIsPhoneInvalid }),
464
- !isPhoneInvalid &&
465
- !((getPhoneObj(formState.phoneNumber || '').countryCode +
466
- ' ' +
467
- getPhoneObj(formState.phoneNumber || '').phoneLine).length > PHONE_LIMIT) &&
468
- !(submitButtonIsClicked &&
469
- !isPhoneNumberValid(formState.phoneNumber, formState.countryCode)) && (React.createElement(FormHelperText, null,
470
- React.createElement(HelperText, null,
471
- React.createElement(HelperTextItem, { variant: "default" }, t('Note: A current phone/mobile number with the country code helps us support you better. Phone number will be stored in case comments for escalation only – not used for marketing.'))))),
472
- isPhoneInvalid && (React.createElement(FormHelperText, null,
473
- React.createElement(HelperText, null,
474
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Phone number can only have digits.'))))),
475
- submitButtonIsClicked &&
476
- (getPhoneObj(formState.phoneNumber || '').countryCode +
477
- ' ' +
478
- getPhoneObj(formState.phoneNumber || '').phoneLine).length > PHONE_LIMIT && (React.createElement(FormHelperText, null,
479
- React.createElement(HelperText, null,
480
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Phone number cannot be more than {{limit}} digits.', {
481
- limit: PHONE_LIMIT,
482
- }))))),
483
- submitButtonIsClicked &&
484
- isPhoneLineEmpty(formState.phoneNumber, formState.countryCode) && (React.createElement(FormHelperText, null,
485
- React.createElement(HelperText, null,
486
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Phone number is required'))))),
487
- submitButtonIsClicked &&
488
- isPhoneNumberInvalid(formState.phoneNumber, formState.countryCode) &&
489
- !isPhoneInvalid && (React.createElement(FormHelperText, null,
490
- React.createElement(HelperText, null,
491
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Phone number cannot be empty'))))),
492
- submitButtonIsClicked &&
493
- !isEmpty(trimAndReplacePlus(formState.countryCode || '')) &&
494
- !isCountryCodeValid(formState.countryCode) && (React.createElement(FormHelperText, null,
495
- React.createElement(HelperText, null,
496
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Country code is invalid'))))),
497
- submitButtonIsClicked &&
498
- isEmpty(trimAndReplacePlus(formState.countryCode || '')) &&
499
- !isPhoneLineEmpty(formState.phoneNumber, formState.countryCode) &&
500
- !isPhoneInvalid && (React.createElement(FormHelperText, null,
501
- React.createElement(HelperText, null,
502
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Phone number is not valid'))))))),
503
- React.createElement(GridItem, { span: 12 },
504
- React.createElement(FormGroup, { label: React.createElement(React.Fragment, null,
505
- t('Timezone'),
506
- " "), isRequired: true, fieldId: "timezone" },
507
- React.createElement("div", { className: "timezone" },
508
- React.createElement(SingleSelectDropdown, { selected: TIMEZONE_OPTIONS.find((opt) => opt.value === formState.timezone) || {
509
- value: '',
510
- label: 'Select timezone',
511
- }, options: TIMEZONE_OPTIONS, onSelect: (option) => setFormState(Object.assign(Object.assign({}, formState), { timezone: option.value })), placeholder: t('Select timezone') })),
512
- submitButtonIsClicked && !((_o = formState.timezone) === null || _o === void 0 ? void 0 : _o.trim()) && (React.createElement(FormHelperText, null,
513
- React.createElement(HelperText, null,
514
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Timezone is required'))))))),
515
- React.createElement(GridItem, { span: 12 },
516
- React.createElement(FormGroup, { label: React.createElement(React.Fragment, null,
517
- t('Best time to connect regarding escalation'),
518
- " "), isRequired: true, fieldId: "preferred-time" },
519
- React.createElement("div", { className: "pf-v6-u-display-flex pf-v6-u-align-items-center pf-v6-u-flex-nowrap time-fields-container" },
520
- React.createElement("span", { className: "time-label pf-v6-u-mr-sm" }, t('from')),
521
- React.createElement(TimePicker, { time: formState.preferredTimeFrom || '', onChange: (_event, time) => setFormState(Object.assign(Object.assign({}, formState), { preferredTimeFrom: time })), placeholder: "HH:MM", id: "preferred-time-from", "aria-label": t('Preferred time from'), className: "time-input", is24Hour: true, width: "150px", menuAppendTo: "parent", inputProps: {
522
- validated: submitButtonIsClicked && !((_p = formState.preferredTimeFrom) === null || _p === void 0 ? void 0 : _p.trim())
523
- ? ValidatedOptions.error
524
- : ValidatedOptions.default,
525
- } }),
526
- React.createElement("span", { className: "time-label pf-v6-u-mx-md" }, t('to')),
527
- React.createElement(TimePicker, { time: formState.preferredTimeTo || '', onChange: (_event, time) => setFormState(Object.assign(Object.assign({}, formState), { preferredTimeTo: time })), placeholder: "HH:MM", id: "preferred-time-to", "aria-label": t('Preferred time to'), className: "time-input", is24Hour: true, width: "150px", menuAppendTo: "parent", inputProps: {
528
- validated: submitButtonIsClicked &&
529
- (!((_q = formState.preferredTimeTo) === null || _q === void 0 ? void 0 : _q.trim()) ||
530
- !isValidTimeRange(formState.preferredTimeFrom || '', formState.preferredTimeTo || ''))
531
- ? ValidatedOptions.error
532
- : ValidatedOptions.default,
533
- } })),
534
- submitButtonIsClicked &&
535
- (!((_r = formState.preferredTimeFrom) === null || _r === void 0 ? void 0 : _r.trim()) ||
536
- !((_s = formState.preferredTimeTo) === null || _s === void 0 ? void 0 : _s.trim())) && (React.createElement(FormHelperText, null,
537
- React.createElement(HelperText, null,
538
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Preferred time is required'))))),
539
- submitButtonIsClicked &&
540
- ((_t = formState.preferredTimeFrom) === null || _t === void 0 ? void 0 : _t.trim()) &&
541
- ((_u = formState.preferredTimeTo) === null || _u === void 0 ? void 0 : _u.trim()) &&
542
- !isValidTimeRange(formState.preferredTimeFrom, formState.preferredTimeTo) && (React.createElement(FormHelperText, null,
543
- React.createElement(HelperText, null,
544
- React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('End time must be after start time'))))))))))))));
545
- return (React.createElement(Modal, { id: "request-mgmt-escalation-modal", className: "request-escalation-modal pf-m-width-auto", isOpen: props.show, onClose: onCancel, "aria-label": t('Request an escalation'), variant: ModalVariant.large },
546
- React.createElement("div", { className: "modal-wizard-header" },
547
- React.createElement(ModalHeader, { title: t('Request an escalation') }),
548
- React.createElement("a", { href: "/support/escalation", target: "_blank", rel: "noopener noreferrer", className: "pf-v6-u-font-size-sm pf-v6-u-color-200" },
549
- React.createElement(Trans, null, "Learn more about escalation cases."))),
550
- React.createElement(ModalBody, null,
551
- creationError && (React.createElement(AlertMessage, { variant: AlertType.DANGER, title: t('Could not create case escalation'), show: creationError, onClose: onErrorClose, isInline: true, className: "pf-v6-u-mb-md", "aria-label": t('Could not create case escalation') })),
552
- React.createElement(Wizard, { navAriaLabel: t('Escalation request steps'), footer: CustomFooter, nav: customNav },
553
- escalationDetailsStep,
554
- contactDetailsStep))));
171
+ React.createElement(SingleSelectDropdown, { ariaLabel: t('My region'), id: "customer-geo-select", selected: selectedGeo, options: geoOptions, isInvalid: submitButtonIsClicked && isEmpty(formState.geo), placeholder: t('Select a location'), onSelect: (option) => setGeoState(option) }))),
172
+ React.createElement(FormGroup, { isRequired: true, label: t('Subject'), fieldId: "escalation-subject" },
173
+ submitButtonIsClicked && hasLargeSubject && (React.createElement(FormHelperText, null,
174
+ React.createElement(HelperText, null,
175
+ React.createElement(HelperTextItem, { variant: ValidatedOptions.error }, t('Subject cannot be more than {{limit}} characters', {
176
+ limit: ESCALATION_SUBJECT_LENGTH_LIMIT,
177
+ }))))),
178
+ React.createElement(TextInput, { isRequired: true, validated: (submitButtonIsClicked && isEmpty(formState.subject)) || hasLargeSubject
179
+ ? ValidatedOptions.error
180
+ : ValidatedOptions.default, type: "text", placeholder: t('Enter a subject for your request'), id: "subject-input", name: "subject-input", value: formState.subject, onChange: (_event, subject) => onSubjectChange(subject), "aria-label": t('Subject') })),
181
+ React.createElement(FormGroup, { isRequired: true, label: t('Description'), fieldId: "escalation-description" },
182
+ React.createElement(TextArea, { value: formState.description, onChange: (e, value) => setFormStateValue('description', value), isRequired: true, validated: submitButtonIsClicked && isEmpty(formState.description)
183
+ ? ValidatedOptions.error
184
+ : ValidatedOptions.default, "aria-label": t('Description'), id: "description-textarea", placeholder: t('Provide a detailed comment for us to best assist you'), resizeOrientation: "vertical" })),
185
+ React.createElement(FormGroup, { isRequired: true, label: t('Expectations'), fieldId: "escalation-expectations" },
186
+ React.createElement(TextArea, { onChange: (e, value) => setFormStateValue('expectations', value), isRequired: true, validated: submitButtonIsClicked && isEmpty(formState.expectations)
187
+ ? ValidatedOptions.error
188
+ : ValidatedOptions.default, placeholder: t('What do you expect to happen with this escalation?'), id: "expectations-input", value: formState.expectations, "aria-label": t('Expectations'), resizeOrientation: "vertical" })),
189
+ React.createElement(FormGroup, { isRequired: true, label: t('Business impact'), fieldId: "escalation-business-impact" },
190
+ React.createElement(TextArea, { onChange: (e, value) => setFormStateValue('businessImpactDescription', value), isRequired: true, validated: submitButtonIsClicked && isEmpty(formState.businessImpactDescription)
191
+ ? ValidatedOptions.error
192
+ : ValidatedOptions.default, placeholder: t('Does your business impact change with this escalation? Please describe how it changed.'), id: "business-impact-input", value: formState.businessImpactDescription, "aria-label": t('Business impact'), resizeOrientation: "vertical" }))))),
193
+ React.createElement(ModalFooter, null,
194
+ React.createElement(Button, { key: "submit", variant: "primary", onClick: onSubmit, "data-tracking-id": "request-rme-submit", isDisabled: submitButtonIsClicked &&
195
+ (isPostingComment || isUpdatingCase || createEscalationFetch.isFetching || !hasRequiredInfo()), "aria-label": t('Submit') },
196
+ (isPostingComment || isUpdatingCase || createEscalationFetch.isFetching) && (React.createElement(LoadingIndicator, { key: "loading", isInline: true })),
197
+ ' ',
198
+ t('Submit')),
199
+ React.createElement(Button, { key: "cancel", variant: "link", onClick: onCancel, "data-tracking-id": "request-rme-cancel", isDisabled: createEscalationFetch.isFetching || isPostingComment || isUpdatingCase, "aria-label": t('Cancel') }, t('Cancel')))));
555
200
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAS,mBAAmB,EAAiD,MAAM,kBAAkB,CAAC;AAmB7G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,MAAM,qBA4OzC"}
1
+ {"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAS,mBAAmB,EAAiD,MAAM,kBAAkB,CAAC;AAmB7G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,MAAM,qBAgPzC"}
@@ -42,6 +42,7 @@ export default function Case(props) {
42
42
  const currentCaseRef = useRef();
43
43
  const canSeeFeedbackButtons = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_FEEDBACK_BUTTONS);
44
44
  const canReadCase = ability.can(resourceActions.READ, resources.CASE_DETAILS);
45
+ const canManageCase = ability.can(resourceActions.UPDATE, resources.CASE_DETAILS);
45
46
  const canSeeExternalTracker = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_EXTERNAL_TRACKER);
46
47
  const canSeeAttachments = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEE_ATTACHMENTS);
47
48
  const canSeeRMEs = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_RMES);
@@ -146,7 +147,7 @@ export default function Case(props) {
146
147
  React.createElement("div", { className: "support-grid-case-details support-case" }, isFetchingCaseDetails && !isFetchingCaseDetailsError && isEmpty(product) ? (React.createElement(OverviewContentLoader, null)) : (React.createElement(React.Fragment, null,
147
148
  React.createElement("article", { className: "grid-main" },
148
149
  React.createElement("section", { className: "grid-main-section" },
149
- (isFetchingCaseDetailsError || !canReadCase) && (React.createElement(CaseDetailsErrorMessage, { isError: isFetchingCaseDetailsError, errorDetails: caseDetailsError, canReadCase: canReadCase, caseNumber: caseNumber, isInlineError: true })),
150
+ (isFetchingCaseDetailsError || !canReadCase) && (React.createElement(CaseDetailsErrorMessage, { isError: isFetchingCaseDetailsError, errorDetails: caseDetailsError, canReadCase: canReadCase, canManageCase: canManageCase, caseNumber: caseNumber, isInlineError: true })),
150
151
  canReadCase &&
151
152
  (!isFetchingCaseDetails || !isEmpty(product)) &&
152
153
  !isFetchingCaseDetailsError && (React.createElement(React.Fragment, null,
@@ -157,7 +158,7 @@ export default function Case(props) {
157
158
  React.createElement(Switch, null,
158
159
  React.createElement(Route, { path: `${path}/:activeTab?` },
159
160
  React.createElement(CaseDetailsTabs, { basePath: url, caseNumber: caseNumber, routeProps: props.routeProps, tabdRef: caseDetailsTabsRef }))))))),
160
- React.createElement(CaseDetailsAside, { caseNumber: caseNumber }),
161
+ !isFetchingCaseDetailsError && canReadCase && canManageCase && (React.createElement(CaseDetailsAside, { caseNumber: caseNumber })),
161
162
  React.createElement(CaseDetailsModals, { caseNumber: caseNumber, isSecureSupport: loggedInUsersAccount.data.secureSupport, loggedInUserRights: loggedInUserRights }))))),
162
163
  React.createElement(HostnameAwarenessModal, null)));
163
164
  }