@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.
- package/lib/esm/components/AccountInfo/OwnerSelector.d.ts.map +1 -1
- package/lib/esm/components/AccountInfo/OwnerSelector.js +1 -0
- package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.js +51 -406
- package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Case.js +3 -2
- package/lib/esm/components/CaseEditView/CaseDetailsErrorMessage.d.ts +1 -0
- package/lib/esm/components/CaseEditView/CaseDetailsErrorMessage.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseDetailsErrorMessage.js +3 -3
- package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutions.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutions.js +18 -2
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseOpenshiftClusterId/CaseOpenshiftClusterId.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseOpenshiftClusterId/CaseOpenshiftClusterId.js +7 -4
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.js +14 -2
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.js +6 -0
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/VerifyCaseStatusModal/VerifyCaseStatusModal.js +0 -1
- package/lib/esm/components/CaseInformation/SupportLevel.d.ts.map +1 -1
- package/lib/esm/components/CaseInformation/SupportLevel.js +6 -1
- package/lib/esm/components/CaseManagement/NoClusterIDReasonSelector.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/NoClusterIDReasonSelector.js +20 -12
- package/lib/esm/components/CaseManagement/OpenShiftClusterId.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/OpenShiftClusterId.js +7 -2
- package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.d.ts +1 -0
- package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.js +10 -6
- package/lib/esm/components/TroubleshootSection/AskRedHat.d.ts.map +1 -1
- package/lib/esm/components/shared/useIsSectionValid.d.ts.map +1 -1
- package/lib/esm/components/shared/useIsSectionValid.js +7 -8
- package/lib/esm/components/wizardLayout/WizardNavigation.d.ts.map +1 -1
- package/lib/esm/components/wizardLayout/WizardNavigation.js +8 -4
- package/lib/esm/reducers/CaseConstNTypes.d.ts +1 -13
- package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
- package/lib/esm/reducers/CaseConstNTypes.js +0 -12
- package/lib/esm/reducers/CaseHelpers.d.ts.map +1 -1
- package/lib/esm/reducers/CaseHelpers.js +2 -1
- package/lib/esm/reducers/CaseReducer.d.ts +1 -0
- package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
- package/lib/esm/reducers/CaseReducer.js +1 -1
- package/lib/esm/reducers/RouteReducer.d.ts +2 -2
- package/lib/esm/reducers/RouteReducer.d.ts.map +1 -1
- package/lib/esm/reducers/RouteReducer.js +1 -1
- package/lib/esm/scss/_pf-overrides.scss +31 -202
- 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,
|
|
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);
|
package/lib/esm/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestEscalationModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseEditView/ActiveCustomerEscalation/RequestEscalationModal.tsx"],"names":[],"mappings":"
|
|
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,
|
|
12
|
-
import
|
|
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
|
|
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
|
-
|
|
185
|
-
|
|
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((
|
|
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
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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 &&
|
|
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 &&
|
|
373
|
-
React.createElement(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
React.createElement(
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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,
|
|
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
|
}
|