@rh-support/troubleshoot 2.7.53 → 2.7.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Case.js +2 -0
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.js +3 -6
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +9 -3
- package/lib/esm/components/CaseInformation/ContactPhoneNumber.d.ts.map +1 -1
- package/lib/esm/components/CaseInformation/ContactPhoneNumber.js +20 -6
- package/lib/esm/components/CaseManagement/CaseManagement.js +3 -0
- package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.js +178 -74
- package/lib/esm/components/CaseManagement/SendNotifications/SendNotificationsPopOver.d.ts +3 -0
- package/lib/esm/components/CaseManagement/SendNotifications/SendNotificationsPopOver.d.ts.map +1 -0
- package/lib/esm/components/CaseManagement/SendNotifications/SendNotificationsPopOver.js +10 -0
- package/lib/esm/components/IdeaInformation/IdeaInformation.js +2 -1
- package/lib/esm/components/Review/Review.d.ts.map +1 -1
- package/lib/esm/components/Review/Review.js +6 -9
- package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts.map +1 -1
- package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.js +10 -1
- package/lib/esm/components/shared/fileUpload/useFileUploader.d.ts.map +1 -1
- package/lib/esm/components/shared/fileUpload/useFileUploader.js +7 -3
- package/lib/esm/graphql/queries/getEscalationDetails.d.ts.map +1 -1
- package/lib/esm/graphql/queries/getEscalationDetails.js +3 -0
- package/lib/esm/graphql/schemas/escalation.d.ts +3 -0
- package/lib/esm/graphql/schemas/escalation.d.ts.map +1 -1
- package/lib/esm/hooks/useS3Upload.d.ts.map +1 -1
- package/lib/esm/hooks/useS3Upload.js +5 -1
- package/lib/esm/hooks/useSyncServerAttachments.d.ts.map +1 -1
- package/lib/esm/hooks/useSyncServerAttachments.js +33 -34
- package/lib/esm/index.js +1 -1
- package/lib/esm/reducers/CaseConstNTypes.d.ts +3 -0
- package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
- package/lib/esm/reducers/CaseConstNTypes.js +3 -0
- package/lib/esm/reducers/CaseDetailsPageReducer.d.ts.map +1 -1
- package/lib/esm/reducers/CaseDetailsPageReducer.js +20 -4
- package/lib/esm/reducers/CaseReducer.d.ts +11 -1
- package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
- package/lib/esm/reducers/CaseReducer.js +80 -2
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAS,mBAAmB,EAAiD,MAAM,kBAAkB,CAAC;AAoB7G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"Case.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/Case.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAS,mBAAmB,EAAiD,MAAM,kBAAkB,CAAC;AAoB7G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,MAAM,qBAkRzC"}
|
|
@@ -126,6 +126,8 @@ export default function Case(props) {
|
|
|
126
126
|
if (currentCaseRef.current !== targetCaseNumber)
|
|
127
127
|
return;
|
|
128
128
|
const caseSalesforceId = typeof (caseDetails === null || caseDetails === void 0 ? void 0 : caseDetails.id) === 'string' ? caseDetails.id : undefined;
|
|
129
|
+
// Case watchers are loaded when the Management tab / CaseContactSelector mounts
|
|
130
|
+
// (local pill state owns adds/deletes after that).
|
|
129
131
|
if (canSeeRMEs && caseSalesforceId) {
|
|
130
132
|
fetchCaseEscalations((action) => currentCaseRef.current === targetCaseNumber && caseDetailsPageDispatch(action), caseSalesforceId, apolloClient, true, includeSecureSupportCases);
|
|
131
133
|
}
|
|
@@ -12,7 +12,7 @@ import CaseLabels from '../../../CaseInformation/CaseLabels';
|
|
|
12
12
|
import Fts from '../../../CaseInformation/Fts';
|
|
13
13
|
// import { Cep } from '../../../CaseManagement/Cep';
|
|
14
14
|
// import { RHAssociatesSelector } from '../../../CaseManagement/RHAssociatesSelector';
|
|
15
|
-
|
|
15
|
+
import CaseContactSelector from '../../../CaseManagement/SendNotifications/CaseContactSelector';
|
|
16
16
|
import { PartnerCaseHelper } from '../../ShareCase/PartnerCaseHelper';
|
|
17
17
|
// TODO: Uncomment when Share with partner is re-enabled
|
|
18
18
|
// import { ShareWithPartner } from '../../ShareCase/PartnerShare';
|
|
@@ -39,11 +39,7 @@ export default function CaseDetailsManagement(props) {
|
|
|
39
39
|
// const accountNumber = caseState.caseDetails.accountNumber;
|
|
40
40
|
const showCaseGroupField = useShowCaseGroupField();
|
|
41
41
|
const ability = useContext(AbilityContext);
|
|
42
|
-
|
|
43
|
-
// resourceActions.PATCH,
|
|
44
|
-
// resources.CASE_DETAILS,
|
|
45
|
-
// CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS
|
|
46
|
-
// );
|
|
42
|
+
const canSeeEmailNotifications = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS);
|
|
47
43
|
const canSeeInternalStatus = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_INTERNAL_STATUS);
|
|
48
44
|
const canSeeSBRGroups = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SBR_GROUP);
|
|
49
45
|
return (React.createElement(React.Fragment, null,
|
|
@@ -64,6 +60,7 @@ export default function CaseDetailsManagement(props) {
|
|
|
64
60
|
React.createElement(FlexItem, { flex: { default: 'flex_1' } },
|
|
65
61
|
React.createElement(CaseLabels, null))),
|
|
66
62
|
React.createElement(CaseReferenceNumber, null),
|
|
63
|
+
canSeeEmailNotifications && React.createElement(CaseContactSelector, null),
|
|
67
64
|
React.createElement(Fts, { inlineEditable: true }),
|
|
68
65
|
React.createElement(SFDCUrl, null)))));
|
|
69
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAW7F,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAmB5E,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAW7F,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAmB5E,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,qBA4cxC"}
|
|
@@ -214,7 +214,7 @@ export function PostComment(props) {
|
|
|
214
214
|
const checkCommentSignature = derivedPlainText.replace(commentSignature, '');
|
|
215
215
|
const isCommentEmpty = isEmpty(checkCommentSignature === null || checkCommentSignature === void 0 ? void 0 : checkCommentSignature.trim());
|
|
216
216
|
const onPostComment = () => __awaiter(this, void 0, void 0, function* () {
|
|
217
|
-
var _a, _b;
|
|
217
|
+
var _a, _b, _c, _d;
|
|
218
218
|
if (canEditCase.alert())
|
|
219
219
|
return;
|
|
220
220
|
if (!commentText)
|
|
@@ -257,8 +257,14 @@ export function PostComment(props) {
|
|
|
257
257
|
ToastNotification.addSuccessMessage(t('Comment submitted'));
|
|
258
258
|
setCssCommentAgreed(false);
|
|
259
259
|
}
|
|
260
|
-
catch (
|
|
261
|
-
|
|
260
|
+
catch (error) {
|
|
261
|
+
const statusCode = (_c = error === null || error === void 0 ? void 0 : error.statusCode) !== null && _c !== void 0 ? _c : (_d = error === null || error === void 0 ? void 0 : error.networkError) === null || _d === void 0 ? void 0 : _d.statusCode;
|
|
262
|
+
if (statusCode === 403) {
|
|
263
|
+
ToastNotification.addDangerMessage(t('Could not submit comment. Remove or rephrase code/stack-trace text and try again.'));
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
ToastNotification.addDangerMessage(t('Could not submit comment. Please refresh the page and try again.'));
|
|
267
|
+
}
|
|
262
268
|
}
|
|
263
269
|
finally {
|
|
264
270
|
setIsProcessing(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactPhoneNumber.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/ContactPhoneNumber.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ContactPhoneNumber.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/ContactPhoneNumber.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAoF/D,wBAAgB,kBAAkB,sBAqUjC"}
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { ValidatedOptions } from '@patternfly/react-core';
|
|
11
|
-
import { getExactCountry, getPhoneObj, PhoneInput } from '@rh-support/components';
|
|
11
|
+
import { getCountryByIso2, getExactCountry, getPhoneObj, getPreferredCountryIso2FromTimezone, PhoneInput, } from '@rh-support/components';
|
|
12
12
|
import { GlobalMetadataStateContext } from '@rh-support/react-context';
|
|
13
13
|
import isEmpty from 'lodash/isEmpty';
|
|
14
14
|
import isEqual from 'lodash/isEqual';
|
|
@@ -23,7 +23,7 @@ import { setCaseDetails, setCaseState } from '../../reducers/CaseReducer';
|
|
|
23
23
|
import { PDFContext } from '../CaseEditView/PDFContainer';
|
|
24
24
|
import { removeAllChars, trimAndReplacePlus } from '../shared/utils';
|
|
25
25
|
import { ContactPhoneNumberPopOver } from './ContactPhoneNumberPopOver';
|
|
26
|
-
function parsePhone(rawPhone) {
|
|
26
|
+
function parsePhone(rawPhone, preferredCountryIso2) {
|
|
27
27
|
var _a;
|
|
28
28
|
const trimmedPhone = rawPhone === null || rawPhone === void 0 ? void 0 : rawPhone.trim();
|
|
29
29
|
if (!trimmedPhone) {
|
|
@@ -37,7 +37,19 @@ function parsePhone(rawPhone) {
|
|
|
37
37
|
shouldNotSetPhoneCountryCode: false,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
+
const preferredCountry = getCountryByIso2(preferredCountryIso2 || '');
|
|
40
41
|
const rawDigits = removeAllChars(trimmedPhone);
|
|
42
|
+
if (preferredCountry && rawDigits) {
|
|
43
|
+
const dial = String(preferredCountry.dialCode);
|
|
44
|
+
const nationalNumber = rawDigits.startsWith(dial) && rawDigits.length > dial.length + 6
|
|
45
|
+
? rawDigits.substring(dial.length)
|
|
46
|
+
: rawDigits;
|
|
47
|
+
return {
|
|
48
|
+
phoneCountryCode: `+${dial}`,
|
|
49
|
+
phoneAreaCodePrefixLineNumber: nationalNumber,
|
|
50
|
+
shouldNotSetPhoneCountryCode: false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
41
53
|
if (rawDigits.length > 10) {
|
|
42
54
|
const exactCountry = getExactCountry(rawDigits);
|
|
43
55
|
const dialCode = !isEmpty(exactCountry) ? String(exactCountry['dialCode']) : '';
|
|
@@ -118,7 +130,7 @@ export function ContactPhoneNumber() {
|
|
|
118
130
|
}
|
|
119
131
|
};
|
|
120
132
|
const onCountryCodeChange = (phoneCountryCode) => {
|
|
121
|
-
setCaseState(caseDispatch, { hasUserUpdatedSuppliedPhone: true });
|
|
133
|
+
setCaseState(caseDispatch, Object.assign({ hasUserUpdatedSuppliedPhone: true }, (phoneCountryCode ? { shouldNotSetPhoneCountryCode: false } : {})));
|
|
122
134
|
setCaseDetails(caseDispatch, { phoneCountryCode });
|
|
123
135
|
};
|
|
124
136
|
const maxLengthErrorMessage = t('Phone number cannot be more than {{limit}} digits.', {
|
|
@@ -175,7 +187,8 @@ export function ContactPhoneNumber() {
|
|
|
175
187
|
: 'False';
|
|
176
188
|
}
|
|
177
189
|
else {
|
|
178
|
-
const
|
|
190
|
+
const preferredIso2 = getPreferredCountryIso2FromTimezone(loggedInUser.data.timezone || loggedInUser.data.normalizedTZ);
|
|
191
|
+
const parsed = parsePhone(loggedInUser.data.phone, preferredIso2);
|
|
179
192
|
_phoneCountryCode = parsed.phoneCountryCode;
|
|
180
193
|
_phoneAreaCodePrefixLineNumber = parsed.phoneAreaCodePrefixLineNumber;
|
|
181
194
|
setCaseState(caseDispatch, {
|
|
@@ -193,7 +206,8 @@ export function ContactPhoneNumber() {
|
|
|
193
206
|
}
|
|
194
207
|
else {
|
|
195
208
|
// Opening case for another owner — use phone already on selectedOwner
|
|
196
|
-
const
|
|
209
|
+
const preferredIso2 = getPreferredCountryIso2FromTimezone(loggedInUser.data.timezone || loggedInUser.data.normalizedTZ);
|
|
210
|
+
const parsed = parsePhone(selectedOwnerPhone, preferredIso2);
|
|
197
211
|
_phoneAreaCodePrefixLineNumber = parsed.phoneAreaCodePrefixLineNumber;
|
|
198
212
|
_phoneCountryCode = parsed.phoneCountryCode;
|
|
199
213
|
setCaseState(caseDispatch, { shouldNotSetPhoneCountryCode: parsed.shouldNotSetPhoneCountryCode });
|
|
@@ -273,7 +287,7 @@ export function ContactPhoneNumber() {
|
|
|
273
287
|
React.createElement(Trans, null, "Case owner's phone number"),
|
|
274
288
|
React.createElement("span", { className: `form-required ${isExportingPDF ? 'hide-in-pdf' : ''}`, "aria-hidden": true }, "*"),
|
|
275
289
|
ContactPhoneNumberPopOver()),
|
|
276
|
-
React.createElement(PhoneInput, { phoneValue: localFullPhone, countryCode: phoneCountryCode, onPhoneValueChange: onPhoneChange, onCountryCodeChange: onCountryCodeChange, validations: isPhoneNumberValid, invalid: invalid, setInvalid: setInvalid, isLoading: isCasePhoneUpdating, shouldNotSetCountryCode: shouldNotSetPhoneCountryCode, isDisabled: isCasePhoneUpdating }),
|
|
290
|
+
React.createElement(PhoneInput, { phoneValue: localFullPhone, countryCode: phoneCountryCode, onPhoneValueChange: onPhoneChange, onCountryCodeChange: onCountryCodeChange, validations: isPhoneNumberValid, invalid: invalid, setInvalid: setInvalid, isLoading: isCasePhoneUpdating, shouldNotSetCountryCode: shouldNotSetPhoneCountryCode, preferredCountryIso2: getPreferredCountryIso2FromTimezone(loggedInUser.data.timezone || loggedInUser.data.normalizedTZ), isDisabled: isCasePhoneUpdating }),
|
|
277
291
|
!invalid &&
|
|
278
292
|
getPhone.length <= PHONE_LIMIT &&
|
|
279
293
|
!(isPhoneNumberEmpty && isNextBtnClickedToShowValidationError) &&
|
|
@@ -14,6 +14,8 @@ import CaseLabelsCreate from './CaseLabelsCreate';
|
|
|
14
14
|
import CaseLanguageSelector from './CaseLanguageSelector';
|
|
15
15
|
// import { Cep } from './Cep';
|
|
16
16
|
import OpenReferenceNumber from './OpenReferenceNumber';
|
|
17
|
+
// import { RHAssociatesSelector } from './RHAssociatesSelector';
|
|
18
|
+
import CaseContactSelector from './SendNotifications/CaseContactSelector';
|
|
17
19
|
export default function CaseManagement(props) {
|
|
18
20
|
const caseDispatch = useCaseDispatch();
|
|
19
21
|
const showCaseGroupField = useShowCaseGroupField();
|
|
@@ -36,5 +38,6 @@ export default function CaseManagement(props) {
|
|
|
36
38
|
React.createElement(Grid, { hasGutter: true },
|
|
37
39
|
React.createElement(GridItem, { span: 12, xl2: 12, className: "pf-v6-u-mb-xs" },
|
|
38
40
|
React.createElement(CaseLabelsCreate, null))),
|
|
41
|
+
React.createElement(CaseContactSelector, null),
|
|
39
42
|
React.createElement(OpenReferenceNumber, { inlineEditable: false, hideSaveCancel: true })));
|
|
40
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseContactSelector.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseManagement/SendNotifications/CaseContactSelector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CaseContactSelector.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseManagement/SendNotifications/CaseContactSelector.tsx"],"names":[],"mappings":"AAkCA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAmBvE,MAAM,WAAW,MAAM;CAAG;AAG1B,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,qBAmmBzC;AAED,eAAe,mBAAmB,CAAC"}
|
|
@@ -7,11 +7,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { useApolloClient } from '@apollo/client/react';
|
|
10
11
|
import { Button, Tooltip, TooltipPosition } from '@patternfly/react-core';
|
|
12
|
+
import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
|
|
11
13
|
import { CaseContactsSelectorExternal, getHydraContactLabel, PromisifyModal, ToastNotification, usePrevious, } from '@rh-support/components';
|
|
12
14
|
import { GlobalMetadataStateContext, useCanEditCase } from '@rh-support/react-context';
|
|
13
15
|
import { AbilityContext, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
14
|
-
import { dtmTrackEventCaseStepEncountered } from '@rh-support/utils';
|
|
16
|
+
import { dtmTrackEventCaseStepEncountered, fetchCaseWatcherContactsByCaseNumber, isCaseWatcherLimitExceededError, } from '@rh-support/utils';
|
|
15
17
|
import difference from 'lodash/difference';
|
|
16
18
|
import differenceBy from 'lodash/differenceBy';
|
|
17
19
|
import filter from 'lodash/filter';
|
|
@@ -29,11 +31,13 @@ import { Token } from 'react-bootstrap-typeahead';
|
|
|
29
31
|
import { Trans, useTranslation } from 'react-i18next';
|
|
30
32
|
import { useCaseDispatch, useCaseSelector } from '../../../context/CaseContext';
|
|
31
33
|
import { useCaseUpdateErrorMessage } from '../../../hooks/useCaseUpdateErrorMessage';
|
|
32
|
-
import {
|
|
34
|
+
import { MAX_NOTIFICATION_CONTACTS, MAX_NOTIFICATION_CONTACTS_WITH_OVERFLOW } from '../../../reducers/CaseConstNTypes';
|
|
35
|
+
import { createCaseWatchers, deleteCaseWatchers, setNotifiedUser, setSelectedCaseGroupUsers, } from '../../../reducers/CaseReducer';
|
|
33
36
|
import { PDFContext } from '../../CaseEditView/PDFContainer';
|
|
34
37
|
import { useCustomEmails } from '../../CaseEditView/Tabs/CaseDetails/useCustomEmails';
|
|
35
38
|
import { AddContactToGroupModal } from './AddContactToGroupModal';
|
|
36
39
|
import { NonOrgCaseNotifyeesSelector } from './NonOrgCaseNotifyeesSelector';
|
|
40
|
+
import { SendNotificationsPopOver } from './SendNotificationsPopOver';
|
|
37
41
|
function CaseContactSelector(props) {
|
|
38
42
|
var _a;
|
|
39
43
|
const ability = useContext(AbilityContext);
|
|
@@ -41,11 +45,12 @@ function CaseContactSelector(props) {
|
|
|
41
45
|
const [isAssociatesUpdating, setIsAssociatesUpdating] = useState(false);
|
|
42
46
|
const { t } = useTranslation();
|
|
43
47
|
const caseUpdateError = useCaseUpdateErrorMessage();
|
|
44
|
-
const
|
|
48
|
+
const apolloClient = useApolloClient();
|
|
49
|
+
const { accountNumber, caseNumber, caseSalesforceId, contactSsoUsername, selectedOwner, customEmailsList, product, selectedCaseGroupUsers, ownersCaseGroups, groupNumber, createdById, version, isCaseOwnerUpdating, selectedAccountDetails, } = useCaseSelector((state) => ({
|
|
45
50
|
accountNumber: state.caseDetails.accountNumberRef,
|
|
46
51
|
caseNumber: state.caseDetails.caseNumber,
|
|
52
|
+
caseSalesforceId: state.caseDetails.id,
|
|
47
53
|
contactSsoUsername: state.caseDetails.contactSSOName,
|
|
48
|
-
selectedNotificationContacts: state.selectedNotificationContacts,
|
|
49
54
|
selectedOwner: state.selectedOwner,
|
|
50
55
|
customEmailsList: state.customEmailsList,
|
|
51
56
|
selectedCaseGroupUsers: state.selectedCaseGroupUsers,
|
|
@@ -72,51 +77,155 @@ function CaseContactSelector(props) {
|
|
|
72
77
|
const nonOrgTypeaheadRef = useRef(null);
|
|
73
78
|
const canEditCase = useCanEditCase();
|
|
74
79
|
const toolTipRef = useRef();
|
|
75
|
-
const
|
|
76
|
-
|
|
80
|
+
const [localNotificationContacts, setLocalNotificationContacts] = useState([]);
|
|
81
|
+
const localNotificationContactsRef = useRef([]);
|
|
82
|
+
localNotificationContactsRef.current = localNotificationContacts;
|
|
83
|
+
const hasLocalEditsRef = useRef(false);
|
|
84
|
+
const apolloClientRef = useRef(apolloClient);
|
|
85
|
+
apolloClientRef.current = apolloClient;
|
|
86
|
+
const caseDispatchRef = useRef(caseDispatch);
|
|
87
|
+
caseDispatchRef.current = caseDispatch;
|
|
88
|
+
const syncLocalNotificationContacts = (contacts) => {
|
|
89
|
+
hasLocalEditsRef.current = true;
|
|
90
|
+
localNotificationContactsRef.current = contacts;
|
|
91
|
+
setLocalNotificationContacts(contacts);
|
|
92
|
+
setNotifiedUser(caseDispatchRef.current, contacts);
|
|
93
|
+
};
|
|
94
|
+
const clearLocalNotificationContacts = () => {
|
|
95
|
+
hasLocalEditsRef.current = false;
|
|
96
|
+
localNotificationContactsRef.current = [];
|
|
97
|
+
setLocalNotificationContacts([]);
|
|
98
|
+
setNotifiedUser(caseDispatchRef.current, []);
|
|
99
|
+
};
|
|
100
|
+
// GET watchers only when Management tab (this component) mounts — never on option select / create watcher.
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
hasLocalEditsRef.current = false;
|
|
103
|
+
if (!caseNumber || !canSeeEmailNotifications) {
|
|
104
|
+
clearLocalNotificationContacts();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
let cancelled = false;
|
|
108
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
try {
|
|
110
|
+
const contacts = yield fetchCaseWatcherContactsByCaseNumber(apolloClientRef.current, caseNumber);
|
|
111
|
+
if (cancelled)
|
|
112
|
+
return;
|
|
113
|
+
if (hasLocalEditsRef.current) {
|
|
114
|
+
const local = localNotificationContactsRef.current;
|
|
115
|
+
const serverBySso = new Map(contacts.map((c) => [c.ssoUsername, c]));
|
|
116
|
+
const mergedLocal = local.map((c) => {
|
|
117
|
+
const server = serverBySso.get(c.ssoUsername);
|
|
118
|
+
return server ? Object.assign(Object.assign({}, c), server) : c;
|
|
119
|
+
});
|
|
120
|
+
const localSso = new Set(local.map((c) => c.ssoUsername));
|
|
121
|
+
const onlyOnServer = contacts.filter((c) => !localSso.has(c.ssoUsername));
|
|
122
|
+
const merged = uniqBy([...onlyOnServer, ...mergedLocal], 'ssoUsername');
|
|
123
|
+
// Hydrate from GET without marking as a user edit.
|
|
124
|
+
localNotificationContactsRef.current = merged;
|
|
125
|
+
setLocalNotificationContacts(merged);
|
|
126
|
+
setNotifiedUser(caseDispatchRef.current, merged);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
localNotificationContactsRef.current = contacts;
|
|
130
|
+
setLocalNotificationContacts(contacts);
|
|
131
|
+
setNotifiedUser(caseDispatchRef.current, contacts);
|
|
132
|
+
}
|
|
133
|
+
catch (_a) { }
|
|
134
|
+
}))();
|
|
135
|
+
return () => {
|
|
136
|
+
cancelled = true;
|
|
137
|
+
hasLocalEditsRef.current = false;
|
|
138
|
+
localNotificationContactsRef.current = [];
|
|
139
|
+
setLocalNotificationContacts([]);
|
|
140
|
+
setNotifiedUser(caseDispatchRef.current, []);
|
|
141
|
+
};
|
|
142
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
143
|
+
}, [caseNumber, canSeeEmailNotifications]);
|
|
144
|
+
const getSelectedNotificationCount = () => customEmailsList.data.length + localNotificationContacts.length;
|
|
145
|
+
const addCaseContact = (toAdd) => __awaiter(this, void 0, void 0, function* () {
|
|
146
|
+
if (!toAdd.length)
|
|
147
|
+
return;
|
|
148
|
+
const currentCount = getSelectedNotificationCount();
|
|
149
|
+
if (currentCount >= MAX_NOTIFICATION_CONTACTS_WITH_OVERFLOW) {
|
|
150
|
+
clearNonOrgTypeahead();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const contactsBeforeAdd = localNotificationContactsRef.current;
|
|
154
|
+
const alreadyAtLimit = currentCount >= MAX_NOTIFICATION_CONTACTS;
|
|
155
|
+
const toAddSso = new Set(map(toAdd, (c) => c.ssoUsername));
|
|
156
|
+
// Show pills from local selection immediately (before any create / GET).
|
|
157
|
+
const optimistic = uniqBy([
|
|
158
|
+
...contactsBeforeAdd,
|
|
159
|
+
...toAdd.map((c) => (Object.assign(Object.assign(Object.assign({}, c), { isInternal: false }), (alreadyAtLimit ? { isNotificationOverLimit: true } : {})))),
|
|
160
|
+
], 'ssoUsername');
|
|
161
|
+
syncLocalNotificationContacts(optimistic);
|
|
162
|
+
clearNonOrgTypeahead();
|
|
163
|
+
if (isEmpty(caseNumber)) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (!caseSalesforceId) {
|
|
167
|
+
syncLocalNotificationContacts(contactsBeforeAdd);
|
|
168
|
+
throw new Error('Case Salesforce Id is required to add a watcher');
|
|
169
|
+
}
|
|
170
|
+
if (alreadyAtLimit) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
77
173
|
setIsAssociatesUpdating(true);
|
|
78
174
|
try {
|
|
79
|
-
yield
|
|
175
|
+
const created = yield createCaseWatchers(caseDispatch, apolloClient, caseSalesforceId, toAdd);
|
|
176
|
+
const merged = localNotificationContactsRef.current.map((contact) => {
|
|
177
|
+
const match = find(created, (c) => c.ssoUsername === contact.ssoUsername);
|
|
178
|
+
return match ? Object.assign(Object.assign(Object.assign({}, contact), match), { isInternal: false }) : contact;
|
|
179
|
+
});
|
|
180
|
+
const mergedSso = new Set(map(merged, (c) => c.ssoUsername));
|
|
181
|
+
const missing = filter(created, (c) => !mergedSso.has(c.ssoUsername)).map((c) => (Object.assign(Object.assign({}, c), { isInternal: false })));
|
|
182
|
+
syncLocalNotificationContacts(uniqBy([...merged, ...missing], 'ssoUsername'));
|
|
80
183
|
setIsAssociatesUpdating(false);
|
|
81
184
|
ToastNotification.addSuccessMessage(t(`Contact has been successfully added`));
|
|
82
185
|
}
|
|
83
186
|
catch (e) {
|
|
84
187
|
setIsAssociatesUpdating(false);
|
|
85
|
-
|
|
188
|
+
if (isCaseWatcherLimitExceededError(e)) {
|
|
189
|
+
syncLocalNotificationContacts(localNotificationContactsRef.current.map((c) => toAddSso.has(c.ssoUsername) ? Object.assign(Object.assign({}, c), { isNotificationOverLimit: true }) : c));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
syncLocalNotificationContacts(filter(localNotificationContactsRef.current, (c) => !toAddSso.has(c.ssoUsername)));
|
|
193
|
+
caseUpdateError.showFieldError(e, t('Contact'), () => addCaseContact(toAdd));
|
|
194
|
+
throw e;
|
|
86
195
|
}
|
|
87
196
|
});
|
|
88
|
-
const
|
|
89
|
-
const
|
|
197
|
+
const removeCaseContact = (toRemove) => __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
const current = localNotificationContactsRef.current;
|
|
199
|
+
const toRemoveWithWatcherIds = map(toRemove, (item) => {
|
|
200
|
+
const fromState = find(current, (c) => c.ssoUsername === item.ssoUsername);
|
|
201
|
+
return (fromState !== null && fromState !== void 0 ? fromState : item);
|
|
202
|
+
});
|
|
203
|
+
const toRemoveSso = map(toRemoveWithWatcherIds, (item) => item.ssoUsername);
|
|
204
|
+
const before = current;
|
|
205
|
+
syncLocalNotificationContacts(filter(current, (item) => !toRemoveSso.includes(item.ssoUsername)));
|
|
206
|
+
const persistedToRemove = filter(toRemoveWithWatcherIds, (c) => Boolean(c.caseWatcherId));
|
|
207
|
+
if (isEmpty(caseNumber) || persistedToRemove.length === 0) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
90
210
|
setIsAssociatesUpdating(true);
|
|
91
211
|
try {
|
|
92
|
-
yield
|
|
212
|
+
yield deleteCaseWatchers(caseDispatch, apolloClient, persistedToRemove);
|
|
93
213
|
setIsAssociatesUpdating(false);
|
|
94
214
|
ToastNotification.addSuccessMessage(t(`Contact has been successfully removed`));
|
|
95
215
|
}
|
|
96
216
|
catch (e) {
|
|
97
217
|
setIsAssociatesUpdating(false);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const addCaseContact = (toAdd) => __awaiter(this, void 0, void 0, function* () {
|
|
102
|
-
const newContacts = [...selectedNotificationContacts, ...toAdd];
|
|
103
|
-
if (!isEmpty(caseNumber)) {
|
|
104
|
-
yield onCaseContactAdded(toAdd);
|
|
105
|
-
}
|
|
106
|
-
clearNonOrgTypeahead();
|
|
107
|
-
toAdd.length && setNotifiedUser(caseDispatch, uniqBy([...newContacts], 'ssoUsername'));
|
|
108
|
-
});
|
|
109
|
-
const removeCaseContact = (toRemove) => __awaiter(this, void 0, void 0, function* () {
|
|
110
|
-
const toRemoveSso = map(toRemove, (item) => item.ssoUsername);
|
|
111
|
-
const newContacts = filter(selectedNotificationContacts, (item) => !toRemoveSso.includes(item.ssoUsername));
|
|
112
|
-
if (!isEmpty(caseNumber)) {
|
|
113
|
-
yield onCaseContactRemoved(toRemove);
|
|
218
|
+
syncLocalNotificationContacts(before);
|
|
219
|
+
caseUpdateError.showFieldError(e, t('Contact'), () => removeCaseContact(toRemove));
|
|
220
|
+
throw e;
|
|
114
221
|
}
|
|
115
|
-
toRemove.length && setNotifiedUser(caseDispatch, uniqBy([...newContacts], 'ssoUsername'));
|
|
116
222
|
});
|
|
223
|
+
const totalSelectedContactsCount = getSelectedNotificationCount();
|
|
224
|
+
const isOverContactLimit = totalSelectedContactsCount > MAX_NOTIFICATION_CONTACTS;
|
|
117
225
|
const processCaseContacts = (selectedContacts) => __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
const toAdd = filter(differenceBy(selectedContacts,
|
|
119
|
-
|
|
226
|
+
const toAdd = filter(differenceBy(selectedContacts, localNotificationContacts, 'ssoUsername'), (item) => item.ssoUsername !== contactSsoUsername);
|
|
227
|
+
// Chip X / toggle: Typeahead passes only the changed contact(s), not the full selection.
|
|
228
|
+
const toRemove = filter(intersectionBy(selectedContacts, localNotificationContacts, 'ssoUsername'), (item) => item.ssoUsername !== contactSsoUsername);
|
|
120
229
|
(toAdd.length || toRemove.length) && clearErrorState();
|
|
121
230
|
if ((toAdd || []).length > 0) {
|
|
122
231
|
if (loggedInUserRights.data.isOrgAdmin()) {
|
|
@@ -198,43 +307,40 @@ function CaseContactSelector(props) {
|
|
|
198
307
|
});
|
|
199
308
|
const onNotifiedUserChange = (...args_1) => __awaiter(this, [...args_1], void 0, function* (selectedContacts = [], throwTrackEvent = false) {
|
|
200
309
|
// check if selection changed
|
|
201
|
-
const alreadySelected = [
|
|
202
|
-
...customEmailsList.data,
|
|
203
|
-
...filter(selectedNotificationContacts, (c) => !c.isInternal),
|
|
204
|
-
];
|
|
310
|
+
const alreadySelected = [...customEmailsList.data, ...localNotificationContacts];
|
|
205
311
|
if (alreadySelected.length !== 1 && xor(alreadySelected, selectedContacts).length === 0)
|
|
206
312
|
return;
|
|
207
313
|
if (canEditCase.alert())
|
|
208
314
|
return;
|
|
209
315
|
const allSelectedContacts = [...selectedContacts];
|
|
210
|
-
const selectedCustomEmails = remove(allSelectedContacts, (item) => item.customOption || item.emailAddress).map((item) => item.label || item.emailAddress || item.ssoUsername);
|
|
316
|
+
const selectedCustomEmails = remove(allSelectedContacts, (item) => item.customOption || (item.emailAddress && !item.ssoUsername)).map((item) => item.label || item.emailAddress || item.ssoUsername);
|
|
211
317
|
yield processCustomEmails(selectedCustomEmails);
|
|
212
318
|
yield processCaseContacts(allSelectedContacts);
|
|
213
319
|
if (throwTrackEvent) {
|
|
214
320
|
dtmTrackEventCaseStepEncountered('follow', caseNumber, product, version);
|
|
215
321
|
}
|
|
216
322
|
});
|
|
217
|
-
/** Reset
|
|
323
|
+
/** Reset notification contacts when selected account number changes */
|
|
218
324
|
useEffect(() => {
|
|
219
325
|
if (accountNumber === previousAccountNumber || isEmpty(previousAccountNumber))
|
|
220
326
|
return;
|
|
221
|
-
|
|
327
|
+
syncLocalNotificationContacts([]);
|
|
222
328
|
}, [accountNumber, caseDispatch, previousAccountNumber]);
|
|
223
329
|
const isCurrentUserCaseContact = contactSsoUsername === loggedInUser.data.ssoUsername;
|
|
224
330
|
const isCurrentUserCaseCreator = loggedInUserRights.data.getUserFullName() === createdById;
|
|
225
|
-
const isCurrentUserSelectedExternalNotifiedUser = () => !!find(
|
|
331
|
+
const isCurrentUserSelectedExternalNotifiedUser = () => !!find(localNotificationContacts, (c) => !c.isInternal && c.ssoUsername === loggedInUser.data.ssoUsername);
|
|
226
332
|
const showAddWatchButton = () => !isCurrentUserCaseContact &&
|
|
227
333
|
loggedInUserRights.data.isExternal() &&
|
|
228
334
|
!isCurrentUserSelectedExternalNotifiedUser();
|
|
229
335
|
const showRemoveWatchButton = () => loggedInUserRights.data.isExternal() &&
|
|
230
336
|
(isCurrentUserSelectedExternalNotifiedUser() || isCurrentUserCaseContact);
|
|
231
337
|
const addCurrentUser = () => __awaiter(this, void 0, void 0, function* () {
|
|
232
|
-
onNotifiedUserChange([...
|
|
338
|
+
onNotifiedUserChange([...localNotificationContacts, ...customEmailsList.data, loggedInUser.data], true);
|
|
233
339
|
});
|
|
234
340
|
const removeCurrentUser = () => {
|
|
235
341
|
if (isCurrentUserSelectedExternalNotifiedUser()) {
|
|
236
342
|
onNotifiedUserChange([
|
|
237
|
-
...filter(
|
|
343
|
+
...filter(localNotificationContacts, (contact) => contact.ssoUsername !== loggedInUser.data.ssoUsername),
|
|
238
344
|
...customEmailsList.data,
|
|
239
345
|
]);
|
|
240
346
|
}
|
|
@@ -266,40 +372,38 @@ function CaseContactSelector(props) {
|
|
|
266
372
|
if (!canSeeEmailNotifications)
|
|
267
373
|
return React.createElement(React.Fragment, null);
|
|
268
374
|
return (React.createElement("div", { className: "form-group pf-v6-u-mb-md" },
|
|
269
|
-
React.createElement("label", {
|
|
375
|
+
React.createElement("label", { htmlFor: "open-case-notifications" },
|
|
270
376
|
React.createElement(Trans, null, "Send notifications"),
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
...filter(selectedNotificationContacts, (c) => !c.isInternal),
|
|
303
|
-
], dataTrackingId: "non-org-admin-contact-selector", onChange: onNotifiedUserChange, isChipDisabled: !isCurrentUserCaseCreator && !!caseNumber, accountNumber: accountNumber, groupNumber: groupNumber, typeaheadRef: nonOrgTypeaheadRef, contactSsoUsername: contactSsoUsername })))));
|
|
377
|
+
SendNotificationsPopOver()),
|
|
378
|
+
loggedInUserRights.data.isOrgAdmin() ? (React.createElement(React.Fragment, null,
|
|
379
|
+
React.createElement("div", { "data-tracking-id": "send-notification-listbox" },
|
|
380
|
+
React.createElement(CaseContactsSelectorExternal, { isDisabled: isUpdatingCustomEmails || isAssociatesUpdating, groupContactsAndEmails: true, allowCustomEmailAdd: true, contactSsoUsername: contactSsoUsername !== null && contactSsoUsername !== void 0 ? contactSsoUsername : '', loggedInUserRights: loggedInUserRights.data, selectedAccountNumber: accountNumber, salesforceAccountId: (_a = selectedAccountDetails.data) === null || _a === void 0 ? void 0 : _a.salesforceAccountId, selected: [...customEmailsList.data, ...localNotificationContacts], contactsToExclude: !isEmpty(selectedOwner.data) ? [selectedOwner.data] : [], onChange: onNotifiedUserChange, clearButton: true, multiple: true, maxSelections: MAX_NOTIFICATION_CONTACTS, placeholder: t('Search contacts by name, email, or username'), id: "open-case-notifications", name: "open-case-notifications", className: "react-select-custom", renderToken: renderToken, isUpdating: isAssociatesUpdating ||
|
|
381
|
+
customEmailsList.isFetching ||
|
|
382
|
+
isUpdatingCustomEmails ||
|
|
383
|
+
isCaseOwnerUpdating, isExportingPDF: isExportingPDF, customEmails: accountCustomEmails.data || [], canAddNew: onAddNew, getCreateNewText: getCreateNewText, noOptionsFoundMessage: t('No email address associated with your account matches your search.') })),
|
|
384
|
+
!showGroupPermissionError && !showAccountPermissionError && !isOverContactLimit && (React.createElement("p", { className: "form-instructions" },
|
|
385
|
+
React.createElement(Trans, null, "Include someone from your account to inform about the status of this case."))),
|
|
386
|
+
isOverContactLimit && !isExportingPDF && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
387
|
+
React.createElement(ExclamationCircleIcon, { color: "#c9190b", className: "pf-v6-u-mr-sm" }),
|
|
388
|
+
React.createElement(Trans, { i18nKey: "You can add up to {{limit}} people. Remove someone before adding another.", values: { limit: MAX_NOTIFICATION_CONTACTS } }))),
|
|
389
|
+
showGroupPermissionError && !isExportingPDF && (React.createElement("p", { className: "form-instructions form-invalid" }, loggedInUserRights.data.isOrgAdmin() && (React.createElement(Trans, null,
|
|
390
|
+
"Please",
|
|
391
|
+
' ',
|
|
392
|
+
React.createElement(Button, { variant: "link", isInline: true, component: "span", onClick: onAddContactToGroupBtnClick }, "add this person to the selected group"),
|
|
393
|
+
' ',
|
|
394
|
+
"if you want to send notifications about this case.")))),
|
|
395
|
+
showAccountPermissionError && !isExportingPDF && (React.createElement("p", { className: "form-instructions form-invalid" }, loggedInUserRights.data.isOrgAdmin() && (React.createElement(Trans, null,
|
|
396
|
+
emailToAdd,
|
|
397
|
+
" is not listed under your account. You can always",
|
|
398
|
+
' ',
|
|
399
|
+
React.createElement(Button, { variant: "link", isInline: true, component: "span", onClick: onAddEmailToAccountBtnClick }, "add them at the account level"))))),
|
|
400
|
+
caseNumber && showAddWatchButton() && !isExportingPDF && (React.createElement(Button, { className: "add-watcher-button", variant: "secondary", onClick: addCurrentUser, type: "button", "data-tracking-id": "case-add-me-watcher", isDisabled: isUpdatingCustomEmails || isAssociatesUpdating },
|
|
401
|
+
React.createElement(Trans, null, "Add me as a watcher"))),
|
|
402
|
+
caseNumber && showRemoveWatchButton() && !isExportingPDF && (React.createElement("div", { className: "remove-me-as-watcher pf-v6-u-display-inline-block" }, isCurrentUserCaseContact ? (React.createElement(React.Fragment, null,
|
|
403
|
+
React.createElement(Tooltip, { trigger: 'mouseenter focus', triggerRef: toolTipRef, position: TooltipPosition.top, content: React.createElement(Trans, null, "You are case contact and therefore you cannot be removed as watcher") }),
|
|
404
|
+
React.createElement("div", { className: "pf-v6-u-display-inline-block", ref: toolTipRef },
|
|
405
|
+
React.createElement(Button, { className: "remove-watcher-button", variant: "tertiary", onClick: removeCurrentUser, type: "button", isDisabled: true, "data-tracking-id": "case-remove-me-watcher" },
|
|
406
|
+
React.createElement(Trans, null, "Remove me as a watcher"))))) : (React.createElement(Button, { className: "remove-watcher-button", variant: "secondary", onClick: removeCurrentUser, isDisabled: isUpdatingCustomEmails || isAssociatesUpdating, type: "button", "data-tracking-id": "case-remove-me-watcher" },
|
|
407
|
+
React.createElement(Trans, null, "Remove me as a watcher"))))))) : (React.createElement(NonOrgCaseNotifyeesSelector, { id: "open-case-notifications", placeholder: t('Enter an email address or username for the person you want to notify'), isDisabled: isAssociatesUpdating || customEmailsList.isFetching || isUpdatingCustomEmails, selectedItems: [...customEmailsList.data, ...localNotificationContacts], dataTrackingId: "non-org-admin-contact-selector", onChange: onNotifiedUserChange, isChipDisabled: !isCurrentUserCaseCreator && !!caseNumber, accountNumber: accountNumber, groupNumber: groupNumber, typeaheadRef: nonOrgTypeaheadRef, contactSsoUsername: contactSsoUsername }))));
|
|
304
408
|
}
|
|
305
409
|
export default CaseContactSelector;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SendNotificationsPopOver.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseManagement/SendNotifications/SendNotificationsPopOver.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,eAAO,MAAM,wBAAwB,yBAyBpC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Popover, PopoverPosition } from '@patternfly/react-core';
|
|
2
|
+
import QuestionCircleIcon from '@patternfly/react-icons/dist/js/icons/question-circle-icon';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Trans, useTranslation } from 'react-i18next';
|
|
5
|
+
export const SendNotificationsPopOver = () => {
|
|
6
|
+
const { t } = useTranslation();
|
|
7
|
+
return (React.createElement(Popover, { "aria-label": t('Who can receive notifications info'), position: PopoverPosition.top, headerContent: React.createElement(Trans, null, "Who can receive notifications?"), bodyContent: React.createElement("p", null,
|
|
8
|
+
React.createElement(Trans, null, "Only verified contacts associated with your account can be added. Notification emails include limited case details, so recipients must sign in to the Customer Portal to view the full update.")), closeBtnAriaLabel: t('Close') },
|
|
9
|
+
React.createElement(QuestionCircleIcon, { className: "pf-v6-u-ml-xs icon-size cursor-pointer", "aria-label": t('Who can receive notifications info'), color: "#5e40be" })));
|
|
10
|
+
};
|
|
@@ -21,7 +21,7 @@ import CaseLanguageSelector from '../CaseManagement/CaseLanguageSelector';
|
|
|
21
21
|
// import { Cep } from '../CaseManagement/Cep';
|
|
22
22
|
import OpenReferenceNumber from '../CaseManagement/OpenReferenceNumber';
|
|
23
23
|
// import { RHAssociatesSelector } from '../CaseManagement/RHAssociatesSelector';
|
|
24
|
-
|
|
24
|
+
import CaseContactSelector from '../CaseManagement/SendNotifications/CaseContactSelector';
|
|
25
25
|
import KtQuestions from '../ImproveCase/KtQuestions';
|
|
26
26
|
export default function IdeaInformation() {
|
|
27
27
|
const { t } = useTranslation();
|
|
@@ -111,5 +111,6 @@ export default function IdeaInformation() {
|
|
|
111
111
|
React.createElement(Grid, { hasGutter: true },
|
|
112
112
|
React.createElement(GridItem, { span: 12, xl2: 12, className: "pf-v6-u-mb-xs" },
|
|
113
113
|
React.createElement(CaseLabelsCreate, null))),
|
|
114
|
+
React.createElement(CaseContactSelector, null),
|
|
114
115
|
React.createElement(OpenReferenceNumber, { inlineEditable: false, hideSaveCancel: true }))))));
|
|
115
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Review.d.ts","sourceRoot":"","sources":["../../../../src/components/Review/Review.tsx"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"Review.d.ts","sourceRoot":"","sources":["../../../../src/components/Review/Review.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAsBlE,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;CACpD;AACD,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,MAAM,qBAmG3C"}
|