@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.
Files changed (38) hide show
  1. package/lib/esm/components/CaseEditView/Case.d.ts.map +1 -1
  2. package/lib/esm/components/CaseEditView/Case.js +2 -0
  3. package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.js +3 -6
  4. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
  5. package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +9 -3
  6. package/lib/esm/components/CaseInformation/ContactPhoneNumber.d.ts.map +1 -1
  7. package/lib/esm/components/CaseInformation/ContactPhoneNumber.js +20 -6
  8. package/lib/esm/components/CaseManagement/CaseManagement.js +3 -0
  9. package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.d.ts.map +1 -1
  10. package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.js +178 -74
  11. package/lib/esm/components/CaseManagement/SendNotifications/SendNotificationsPopOver.d.ts +3 -0
  12. package/lib/esm/components/CaseManagement/SendNotifications/SendNotificationsPopOver.d.ts.map +1 -0
  13. package/lib/esm/components/CaseManagement/SendNotifications/SendNotificationsPopOver.js +10 -0
  14. package/lib/esm/components/IdeaInformation/IdeaInformation.js +2 -1
  15. package/lib/esm/components/Review/Review.d.ts.map +1 -1
  16. package/lib/esm/components/Review/Review.js +6 -9
  17. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts.map +1 -1
  18. package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.js +10 -1
  19. package/lib/esm/components/shared/fileUpload/useFileUploader.d.ts.map +1 -1
  20. package/lib/esm/components/shared/fileUpload/useFileUploader.js +7 -3
  21. package/lib/esm/graphql/queries/getEscalationDetails.d.ts.map +1 -1
  22. package/lib/esm/graphql/queries/getEscalationDetails.js +3 -0
  23. package/lib/esm/graphql/schemas/escalation.d.ts +3 -0
  24. package/lib/esm/graphql/schemas/escalation.d.ts.map +1 -1
  25. package/lib/esm/hooks/useS3Upload.d.ts.map +1 -1
  26. package/lib/esm/hooks/useS3Upload.js +5 -1
  27. package/lib/esm/hooks/useSyncServerAttachments.d.ts.map +1 -1
  28. package/lib/esm/hooks/useSyncServerAttachments.js +33 -34
  29. package/lib/esm/index.js +1 -1
  30. package/lib/esm/reducers/CaseConstNTypes.d.ts +3 -0
  31. package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
  32. package/lib/esm/reducers/CaseConstNTypes.js +3 -0
  33. package/lib/esm/reducers/CaseDetailsPageReducer.d.ts.map +1 -1
  34. package/lib/esm/reducers/CaseDetailsPageReducer.js +20 -4
  35. package/lib/esm/reducers/CaseReducer.d.ts +11 -1
  36. package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
  37. package/lib/esm/reducers/CaseReducer.js +80 -2
  38. 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,qBA+QzC"}
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
- // import CaseContactSelector from '../../../CaseManagement/SendNotifications/CaseContactSelector';
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
- // const canSeeEmailNotifications = ability.can(
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,qBAicxC"}
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 (_c) {
261
- ToastNotification.addDangerMessage(t('Could not submit comment. Please refresh the page and try again.'));
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":"AAMA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAkE/D,wBAAgB,kBAAkB,sBAyTjC"}
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 parsed = parsePhone(loggedInUser.data.phone);
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 parsed = parsePhone(selectedOwnerPhone);
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":"AA2BA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAiBvE,MAAM,WAAW,MAAM;CAAG;AAG1B,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,qBA4dzC;AAED,eAAe,mBAAmB,CAAC"}
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 { addingNotifiedUsers, deleteNotifiedUsers, setNotifiedUser, setSelectedCaseGroupUsers, } from '../../../reducers/CaseReducer';
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 { accountNumber, caseNumber, contactSsoUsername, selectedNotificationContacts, selectedOwner, customEmailsList, product, selectedCaseGroupUsers, ownersCaseGroups, groupNumber, createdById, version, isCaseOwnerUpdating, selectedAccountDetails, } = useCaseSelector((state) => ({
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 onCaseContactAdded = (addedUsers) => __awaiter(this, void 0, void 0, function* () {
76
- const addesUsersSso = map(addedUsers, (u) => ({ ssoUsername: u.ssoUsername }));
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 addingNotifiedUsers(caseDispatch, caseNumber, addesUsersSso);
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
- caseUpdateError.showFieldError(e, t('Contact'), () => onCaseContactAdded(addedUsers));
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 onCaseContactRemoved = (removedUsers) => __awaiter(this, void 0, void 0, function* () {
89
- const ssoUsers = map(removedUsers, (u) => u.ssoUsername);
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 deleteNotifiedUsers(caseDispatch, caseNumber, ssoUsers);
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
- caseUpdateError.showFieldError(e, t('Contact'), () => onCaseContactRemoved(removedUsers));
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, selectedNotificationContacts, 'ssoUsername'), (item) => item.ssoUsername !== contactSsoUsername);
119
- const toRemove = filter(intersectionBy(selectedContacts, selectedNotificationContacts, 'ssoUsername'), (item) => !item.isInternal && item.ssoUsername !== contactSsoUsername);
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 all non-internal selectedNotificationContacts when selected account number changes */
323
+ /** Reset notification contacts when selected account number changes */
218
324
  useEffect(() => {
219
325
  if (accountNumber === previousAccountNumber || isEmpty(previousAccountNumber))
220
326
  return;
221
- setNotifiedUser(caseDispatch, []);
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(selectedNotificationContacts, (c) => !c.isInternal && c.ssoUsername === loggedInUser.data.ssoUsername);
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([...selectedNotificationContacts, ...customEmailsList.data, loggedInUser.data], true);
338
+ onNotifiedUserChange([...localNotificationContacts, ...customEmailsList.data, loggedInUser.data], true);
233
339
  });
234
340
  const removeCurrentUser = () => {
235
341
  if (isCurrentUserSelectedExternalNotifiedUser()) {
236
342
  onNotifiedUserChange([
237
- ...filter(selectedNotificationContacts, (contact) => contact.ssoUsername !== loggedInUser.data.ssoUsername),
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", { className: "react-typeahead-label-wrapper", htmlFor: "get-support-notifications" },
375
+ React.createElement("label", { htmlFor: "open-case-notifications" },
270
376
  React.createElement(Trans, null, "Send notifications"),
271
- loggedInUserRights.data.isOrgAdmin() ? (React.createElement(React.Fragment, null,
272
- React.createElement("div", { "data-tracking-id": "send-notification-listbox" },
273
- 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: [
274
- ...customEmailsList.data,
275
- ...filter(selectedNotificationContacts, (c) => !c.isInternal),
276
- ], contactsToExclude: !isEmpty(selectedOwner.data) ? [selectedOwner.data] : [], onChange: onNotifiedUserChange, clearButton: true, multiple: true, placeholder: t('Search for an email address or username of the person you want to notify'), id: "open-case-notifications", name: "open-case-notifications", className: "react-select-custom", renderToken: renderToken, isUpdating: isAssociatesUpdating ||
277
- customEmailsList.isFetching ||
278
- isUpdatingCustomEmails ||
279
- isCaseOwnerUpdating, isExportingPDF: isExportingPDF, customEmails: accountCustomEmails.data || [], canAddNew: onAddNew, getCreateNewText: getCreateNewText })),
280
- !showGroupPermissionError && !showAccountPermissionError && (React.createElement("p", { className: "form-instructions" },
281
- React.createElement(Trans, null, "Include someone from your account to inform about the status of this case."))),
282
- showGroupPermissionError && !isExportingPDF && (React.createElement("p", { className: "form-instructions form-invalid" }, loggedInUserRights.data.isOrgAdmin() && (React.createElement(Trans, null,
283
- "Please",
284
- ' ',
285
- React.createElement(Button, { variant: "link", isInline: true, component: "span", onClick: onAddContactToGroupBtnClick }, "add this person to the selected group"),
286
- ' ',
287
- "if you want to send notifications about this case.")))),
288
- showAccountPermissionError && !isExportingPDF && (React.createElement("p", { className: "form-instructions form-invalid" }, loggedInUserRights.data.isOrgAdmin() && (React.createElement(Trans, null,
289
- emailToAdd,
290
- " is not listed under your account. You can always",
291
- ' ',
292
- React.createElement(Button, { variant: "link", isInline: true, component: "span", onClick: onAddEmailToAccountBtnClick }, "add them at the account level"))))),
293
- 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 },
294
- React.createElement(Trans, null, "Add me as a watcher"))),
295
- caseNumber && showRemoveWatchButton() && !isExportingPDF && (React.createElement("div", { className: "remove-me-as-watcher pf-v6-u-display-inline-block" }, isCurrentUserCaseContact ? (React.createElement(React.Fragment, null,
296
- 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") }),
297
- React.createElement("div", { className: "pf-v6-u-display-inline-block", ref: toolTipRef },
298
- React.createElement(Button, { className: "remove-watcher-button", variant: "tertiary", onClick: removeCurrentUser, type: "button", isDisabled: true, "data-tracking-id": "case-remove-me-watcher" },
299
- 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" },
300
- 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: [
301
- ...customEmailsList.data,
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,3 @@
1
+ import React from 'react';
2
+ export declare const SendNotificationsPopOver: () => React.JSX.Element;
3
+ //# sourceMappingURL=SendNotificationsPopOver.d.ts.map
@@ -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
- // import CaseContactSelector from '../CaseManagement/SendNotifications/CaseContactSelector';
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,KAA4B,MAAM,OAAO,CAAC;AACjD,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"}
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"}