@rh-support/react-context 2.5.327 → 2.6.11

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 (45) hide show
  1. package/lib/esm/GlobalContextWrapper.d.ts +1 -3
  2. package/lib/esm/GlobalContextWrapper.d.ts.map +1 -1
  3. package/lib/esm/GlobalContextWrapper.js +26 -8
  4. package/lib/esm/components/AccountSelector/AccountSelectorInternal.d.ts +1 -2
  5. package/lib/esm/components/AccountSelector/AccountSelectorInternal.d.ts.map +1 -1
  6. package/lib/esm/components/AccountSelector/AccountSelectorInternal.js +93 -37
  7. package/lib/esm/components/EmbeddedServiceChat/EmbeddedServiceChat.d.ts +6 -0
  8. package/lib/esm/components/EmbeddedServiceChat/EmbeddedServiceChat.d.ts.map +1 -1
  9. package/lib/esm/components/EmbeddedServiceChat/EmbeddedServiceChat.js +17 -51
  10. package/lib/esm/components/EmbeddedServiceChat/embeddedServiceChat.css +1 -51
  11. package/lib/esm/components/SharedModals/CSSUserModal.d.ts.map +1 -1
  12. package/lib/esm/components/SharedModals/CSSUserModal.js +2 -1
  13. package/lib/esm/components/SharedModals/CloseCaseModal.d.ts +2 -2
  14. package/lib/esm/components/SharedModals/CloseCaseModal.d.ts.map +1 -1
  15. package/lib/esm/components/SharedModals/CloseCaseModal.js +23 -7
  16. package/lib/esm/context/CaseStatusContext.d.ts +9 -0
  17. package/lib/esm/context/CaseStatusContext.d.ts.map +1 -0
  18. package/lib/esm/context/CaseStatusContext.js +5 -0
  19. package/lib/esm/hooks/index.d.ts +0 -1
  20. package/lib/esm/hooks/index.d.ts.map +1 -1
  21. package/lib/esm/hooks/index.js +0 -1
  22. package/lib/esm/hooks/useCanEditCase.d.ts +2 -1
  23. package/lib/esm/hooks/useCanEditCase.d.ts.map +1 -1
  24. package/lib/esm/hooks/useCanEditCase.js +9 -2
  25. package/lib/esm/hooks/useChatConfig.d.ts +9 -17
  26. package/lib/esm/hooks/useChatConfig.d.ts.map +1 -1
  27. package/lib/esm/hooks/useChatConfig.js +11 -43
  28. package/lib/esm/hooks/useChatInit.d.ts +9 -13
  29. package/lib/esm/hooks/useChatInit.d.ts.map +1 -1
  30. package/lib/esm/hooks/useChatInit.js +64 -119
  31. package/lib/esm/index.d.ts +1 -0
  32. package/lib/esm/index.d.ts.map +1 -1
  33. package/lib/esm/index.js +2 -0
  34. package/lib/esm/reducers/GlobalMetadataHelpers.d.ts.map +1 -1
  35. package/lib/esm/reducers/GlobalMetadataHelpers.js +2 -6
  36. package/lib/esm/reducers/GlobalMetadataReducer.d.ts +51 -16
  37. package/lib/esm/reducers/GlobalMetadataReducer.d.ts.map +1 -1
  38. package/lib/esm/reducers/GlobalMetadataReducer.js +270 -89
  39. package/package.json +9 -6
  40. package/lib/esm/components/EmbeddedServiceChat/ExtraPreChatInfo.d.ts +0 -12
  41. package/lib/esm/components/EmbeddedServiceChat/ExtraPreChatInfo.d.ts.map +0 -1
  42. package/lib/esm/components/EmbeddedServiceChat/ExtraPreChatInfo.js +0 -29
  43. package/lib/esm/hooks/usePreChatFormDetails.d.ts +0 -12
  44. package/lib/esm/hooks/usePreChatFormDetails.d.ts.map +0 -1
  45. package/lib/esm/hooks/usePreChatFormDetails.js +0 -61
@@ -8,9 +8,7 @@ declare global {
8
8
  MSInputMethodContext: any;
9
9
  portal: any;
10
10
  Raven: any;
11
- embedded_svc: any;
12
- $Lightning: any;
13
- liveAgentDeployment: any;
11
+ embeddedservice_bootstrap: any;
14
12
  }
15
13
  interface Document {
16
14
  documentMode: any;
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalContextWrapper.d.ts","sourceRoot":"","sources":["../../src/GlobalContextWrapper.tsx"],"names":[],"mappings":"AAKA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAcnD,UAAU,MAAM;IACZ,QAAQ,EAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,SAAS,EAAE,GAAG,CAAC;QACf,oBAAoB,EAAE,GAAG,CAAC;QAC1B,MAAM,EAAE,GAAG,CAAC;QACZ,KAAK,EAAE,GAAG,CAAC;QACX,YAAY,EAAE,GAAG,CAAC;QAClB,UAAU,EAAE,GAAG,CAAC;QAChB,mBAAmB,EAAE,GAAG,CAAC;KAC5B;IAED,UAAU,QAAQ;QACd,YAAY,EAAE,GAAG,CAAC;KACrB;CACJ;AAmGD,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,sBAKjD,CAAC"}
1
+ {"version":3,"file":"GlobalContextWrapper.d.ts","sourceRoot":"","sources":["../../src/GlobalContextWrapper.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAenD,UAAU,MAAM;IACZ,QAAQ,EAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,SAAS,EAAE,GAAG,CAAC;QACf,oBAAoB,EAAE,GAAG,CAAC;QAC1B,MAAM,EAAE,GAAG,CAAC;QACZ,KAAK,EAAE,GAAG,CAAC;QACX,yBAAyB,EAAE,GAAG,CAAC;KAClC;IAED,UAAU,QAAQ;QACd,YAAY,EAAE,GAAG,CAAC;KACrB;CACJ;AA0HD,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,sBAKjD,CAAC"}
@@ -7,17 +7,19 @@ 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 { accounts, Config } from '@cee-eng/hydrajs';
11
12
  import { LoginModal } from '@rh-support/components';
12
- import { getApiResourceObject, setSecuredSupport, setStrataHeaders } from '@rh-support/utils';
13
+ import { fetchAndSetSalesforceToken, getApiResourceObject, SALESFORCE_SESSION_EXPIRED_EVENT, setSecuredSupport, setStrataHeaders, } from '@rh-support/utils';
13
14
  import isEmpty from 'lodash/isEmpty';
14
15
  import React, { useEffect, useState } from 'react';
15
16
  import { GlobalMetadataContextProvider, GlobalMetadataDispatchContext } from './context/GlobalMetadataContext';
16
- import { fetchAccountManagers, fetchLoggedInUser, fetchLoggedInUsersAccount, fetchManagedAccounts, fetchUserPreferences, GlobalMetadataReducerConstants, loadPCMConfig, setLoggedInUserJwtToken, } from './reducers/GlobalMetadataReducer';
17
+ import { fetchAccountManagers, fetchCaseRecordTypes, fetchLoggedInUser, fetchLoggedInUsersAccount, fetchManagedAccounts, fetchUserPreferences, GlobalMetadataReducerConstants, loadPCMConfig, setLoggedInUserJwtToken, } from './reducers/GlobalMetadataReducer';
17
18
  function GlobalContextMetadataWrapper() {
18
19
  const [showReLoginModal, setShowReLoginModal] = useState(false);
19
20
  const [showSessionExpiredModal, setShowSessionExpiredModal] = useState(false);
20
21
  const dispatchToGlobalMetadataReducer = React.useContext(GlobalMetadataDispatchContext);
22
+ const apolloClient = useApolloClient();
21
23
  // Configuring callbacks to show modals in case of auth logout or session expiry
22
24
  useEffect(() => {
23
25
  const init = () => __awaiter(this, void 0, void 0, function* () {
@@ -29,21 +31,37 @@ function GlobalContextMetadataWrapper() {
29
31
  setShowSessionExpiredModal(true);
30
32
  }
31
33
  }));
34
+ session.on('AuthRefreshSuccess', () => {
35
+ fetchAndSetSalesforceToken(window.sessionjs.getEncodedToken());
36
+ });
32
37
  });
33
38
  init();
34
39
  }, []);
35
- const loadGlobalMetadata = (loggedInUserJwtToken) => {
40
+ // Show session-expired modal when Salesforce token refresh fails
41
+ useEffect(() => {
42
+ const handleSalesforceSessionExpired = () => {
43
+ setShowSessionExpiredModal(true);
44
+ };
45
+ window.addEventListener(SALESFORCE_SESSION_EXPIRED_EVENT, handleSalesforceSessionExpired);
46
+ return () => window.removeEventListener(SALESFORCE_SESSION_EXPIRED_EVENT, handleSalesforceSessionExpired);
47
+ }, []);
48
+ const loadGlobalMetadata = (loggedInUserJwtToken) => __awaiter(this, void 0, void 0, function* () {
49
+ var _a, _b;
36
50
  setLoggedInUserJwtToken(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
51
+ fetchCaseRecordTypes(dispatchToGlobalMetadataReducer, apolloClient);
37
52
  /**
38
53
  * Even GS4 users can use strata's normal user and account endpoints and thus fetching them before hand. This improves the load time by 4 seconds
39
54
  */
40
- loadPCMConfig(dispatchToGlobalMetadataReducer).then((pcmConfig) => {
41
- fetchLoggedInUser(dispatchToGlobalMetadataReducer, loggedInUserJwtToken, pcmConfig);
42
- });
55
+ loadPCMConfig(dispatchToGlobalMetadataReducer);
56
+ const encodedJwt = (_b = (_a = window.sessionjs) === null || _a === void 0 ? void 0 : _a.getEncodedToken) === null || _b === void 0 ? void 0 : _b.call(_a);
57
+ if (encodedJwt) {
58
+ yield fetchAndSetSalesforceToken(encodedJwt);
59
+ }
60
+ fetchLoggedInUser(dispatchToGlobalMetadataReducer, loggedInUserJwtToken, null, apolloClient);
43
61
  fetchUserPreferences(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
44
62
  fetchManagedAccounts(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
45
63
  fetchAccountManagers(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
46
- fetchLoggedInUsersAccount(dispatchToGlobalMetadataReducer, loggedInUserJwtToken).then((loggedInUserAccount) => {
64
+ fetchLoggedInUsersAccount(dispatchToGlobalMetadataReducer, loggedInUserJwtToken, false, apolloClient).then((loggedInUserAccount) => {
47
65
  setSecuredSupport(loggedInUserAccount === null || loggedInUserAccount === void 0 ? void 0 : loggedInUserAccount.secureSupport);
48
66
  if (loggedInUserAccount === null || loggedInUserAccount === void 0 ? void 0 : loggedInUserAccount.secureSupport) {
49
67
  Config.setUserConfig({ isLoggedInAccountGS4: true });
@@ -51,7 +69,7 @@ function GlobalContextMetadataWrapper() {
51
69
  element && element.classList.add('support-secured');
52
70
  }
53
71
  });
54
- };
72
+ });
55
73
  useEffect(() => {
56
74
  const loggedInUserJwtToken = window.sessionjs.getToken();
57
75
  const getAccountNumber = () => __awaiter(this, void 0, void 0, function* () {
@@ -1,5 +1,4 @@
1
1
  import { IAccount } from '@cee-eng/hydrajs/@types/models/account';
2
- import { IAccountListParams } from '@cee-eng/hydrajs/@types/models/csp/account';
3
2
  import React from 'react';
4
3
  interface IProps {
5
4
  selectedAccounts?: IAccount[];
@@ -8,7 +7,6 @@ interface IProps {
8
7
  canBookmarkAccount?: boolean;
9
8
  suggestBookmarkAccounts?: boolean;
10
9
  onSelect?: (accounts: IAccount[]) => any;
11
- accountListParams?: IAccountListParams;
12
10
  multiple?: boolean;
13
11
  isInValid?: boolean;
14
12
  restrictedOnSubscriptionAbuse?: boolean;
@@ -24,6 +22,7 @@ interface IProps {
24
22
  disabled?: boolean;
25
23
  maxResults?: number;
26
24
  delay?: number;
25
+ showSelectionCountBadge?: boolean;
27
26
  }
28
27
  declare function AccountSelectorInternal(props: IProps): React.JSX.Element;
29
28
  declare namespace AccountSelectorInternal {
@@ -1 +1 @@
1
- {"version":3,"file":"AccountSelectorInternal.d.ts","sourceRoot":"","sources":["../../../../src/components/AccountSelector/AccountSelectorInternal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAqBhF,OAAO,KAA+C,MAAM,OAAO,CAAC;AAKpE,UAAU,MAAM;IACZ,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC9B,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7B,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC;IACzC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAkCD,iBAAS,uBAAuB,CAAC,KAAK,EAAE,MAAM,qBA+S7C;kBA/SQ,uBAAuB;;;AAkThC,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"AccountSelectorInternal.d.ts","sourceRoot":"","sources":["../../../../src/components/AccountSelector/AccountSelectorInternal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AA4BlE,OAAO,KAA4D,MAAM,OAAO,CAAC;AAKjF,UAAU,MAAM;IACZ,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC9B,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7B,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC;AAkCD,iBAAS,uBAAuB,CAAC,KAAK,EAAE,MAAM,qBA8W7C;kBA9WQ,uBAAuB;;;AAiXhC,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -7,18 +7,19 @@ 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 { accounts } from '@cee-eng/hydrajs';
11
- import { Button, Flex, FlexItem, MenuToggle, Select, SelectList, SelectOption, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
12
- import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
10
+ import { useApolloClient } from '@apollo/client/react';
11
+ import { Badge, Button, Flex, FlexItem, MenuToggle, Select, SelectList, SelectOption, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
13
12
  import TimesCircleIcon from '@patternfly/react-icons/dist/js/icons/times-circle-icon';
14
- import { LoadingIndicator, useFetch } from '@rh-support/components';
13
+ import { LoadingIndicator } from '@rh-support/components';
14
+ import { buildSearchAccountsWhere, handleGraphQLSearchAccountsResponse, SEARCH_ACCOUNTS, } from '@rh-support/utils';
15
+ import debounce from 'lodash/debounce';
15
16
  import isEmpty from 'lodash/isEmpty';
16
17
  import isNull from 'lodash/isNull';
17
18
  import isUndefined from 'lodash/isUndefined';
18
19
  import uniqBy from 'lodash/uniqBy';
19
- import React, { useEffect, useMemo, useRef, useState } from 'react';
20
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
20
21
  import { Trans, useTranslation } from 'react-i18next';
21
- import { parseAccountSearchQuery, sortAccountsByQuery } from '../../utils';
22
+ import { sortAccountsByQuery } from '../../utils';
22
23
  const defaultProps = {
23
24
  id: '',
24
25
  className: '',
@@ -50,24 +51,28 @@ const getDisplayName = (account) => {
50
51
  : '';
51
52
  };
52
53
  function AccountSelectorInternal(props) {
53
- const { request, isFetching } = useFetch(accounts.getAccounts, { isAbortable: true });
54
+ const apolloClient = useApolloClient();
54
55
  const [items, setItems] = useState([]);
55
56
  const [selectedItems, setSelectedItems] = useState([]);
56
57
  const [isOpen, setIsOpen] = useState(false);
57
58
  const [isQueryChanged, setIsQueryChanged] = useState(false);
59
+ const [isFetching, setIsFetching] = useState(false);
58
60
  const [query, setQuery] = useState('');
59
61
  const [focusedItemIndex, setFocusedItemIndex] = useState(null);
62
+ const [hasNextPage, setHasNextPage] = useState(false);
63
+ const [endCursor, setEndCursor] = useState('');
64
+ const [currentSearchQuery, setCurrentSearchQuery] = useState('');
60
65
  const textInputRef = useRef();
61
66
  const inputGroupRef = useRef();
67
+ const abortControllerRef = useRef();
62
68
  const { t } = useTranslation();
63
69
  const bookmarkedAccountsDeduped = uniqBy(props.bookmarkedAccounts, (b) => b.accountNumber);
64
70
  const pageSize = 20;
65
- const [resultSize, setResultSize] = useState(pageSize);
66
71
  const setQueryLabel = (selectedItems) => {
67
72
  const item = !isEmpty(selectedItems) && !props.multiple ? selectedItems[0] : {};
68
73
  setQuery(getDisplayName(item));
69
74
  };
70
- const itemsToRender = useMemo(() => (isEmpty(items) ? bookmarkedAccountsDeduped : items.slice(0, props.paginate ? resultSize : items.length)), [items, bookmarkedAccountsDeduped, props.paginate, resultSize]);
75
+ const itemsToRender = useMemo(() => (isEmpty(items) ? bookmarkedAccountsDeduped : items), [items, bookmarkedAccountsDeduped]);
71
76
  useEffect(() => {
72
77
  if (!props.multiple) {
73
78
  const selectedItem = (props.selectedAccounts || [])[0];
@@ -81,11 +86,13 @@ function AccountSelectorInternal(props) {
81
86
  setQueryLabel(selectedItems);
82
87
  // eslint-disable-next-line react-hooks/exhaustive-deps
83
88
  }, [selectedItems, props.multiple]);
84
- const onDisplayMoreClick = (e) => {
89
+ const onDisplayMoreClick = (e) => __awaiter(this, void 0, void 0, function* () {
85
90
  e.stopPropagation();
86
- setResultSize((pre) => Math.min(pre + pageSize, items.length));
87
91
  setIsOpen(true);
88
- };
92
+ if (!hasNextPage || !endCursor || !currentSearchQuery)
93
+ return;
94
+ yield fetchAccounts(currentSearchQuery, endCursor);
95
+ });
89
96
  const dropdownOptions = useMemo(() => {
90
97
  if (isFetching) {
91
98
  return (React.createElement("div", { key: "searching", className: "pf-v6-u-px-md pf-v6-u-py-sm" },
@@ -96,13 +103,9 @@ function AccountSelectorInternal(props) {
96
103
  React.createElement(Trans, null, "No results found")));
97
104
  }
98
105
  return [
99
- ...itemsToRender.map((item, index) => (React.createElement(SelectOption, { isFocused: focusedItemIndex === index, key: index, value: item, hasCheckbox: props.multiple, isSelected: selectedItems.some((account) => item.accountNumber === account.accountNumber) }, props.restrictedOnSubscriptionAbuse && item.subscriptionAbuse ? (React.createElement(Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
100
- React.createElement(FlexItem, { className: "form-instructions form-invalid" }, getDisplayName(item)),
101
- React.createElement(FlexItem, { className: "form-instructions form-invalid pf-v6-u-text-nowrap pf-v6-u-pr-sm" },
102
- React.createElement(InfoCircleIcon, null),
103
- " ",
104
- React.createElement(Trans, null, "Subscription abuse")))) : (React.createElement("span", null, getDisplayName(item)))))),
105
- ...(resultSize < items.length
106
+ ...itemsToRender.map((item, index) => (React.createElement(SelectOption, { isFocused: focusedItemIndex === index, key: index, value: item, hasCheckbox: props.multiple, isSelected: selectedItems.some((account) => item.accountNumber === account.accountNumber) },
107
+ React.createElement("span", null, getDisplayName(item))))),
108
+ ...(hasNextPage
106
109
  ? [
107
110
  React.createElement("div", { className: "pf-v6-c-divider", role: "separator", key: "separator" }),
108
111
  React.createElement(SelectOption, { key: 'diplay-more-option', onClick: onDisplayMoreClick, value: 'display-more' },
@@ -115,18 +118,62 @@ function AccountSelectorInternal(props) {
115
118
  },
116
119
  // eslint-disable-next-line react-hooks/exhaustive-deps
117
120
  [items, bookmarkedAccountsDeduped, isFetching, itemsToRender, isQueryChanged]);
118
- const fetchAccounts = (rawQuery) => __awaiter(this, void 0, void 0, function* () {
119
- if (isEmpty(rawQuery === null || rawQuery === void 0 ? void 0 : rawQuery.trim())) {
121
+ const fetchAccounts = useCallback((searchQuery, afterCursor) => __awaiter(this, void 0, void 0, function* () {
122
+ if (isEmpty(searchQuery)) {
120
123
  return;
121
124
  }
122
- const { query: searchQuery, queryKey } = parseAccountSearchQuery(rawQuery);
123
- const fields = ['accountNumber', 'accountId', 'name', 'subscriptionAbuse'].join(',');
124
- const params = Object.assign({ fields, limit: 60, accountNumberNotNull: true }, (queryKey === 'accountNumber' ? { accountNumberLike: searchQuery } : { nameLike: searchQuery }));
125
- const response = request && (yield request(params));
126
- const options = response && response.items && response.items.length ? response.items : [];
127
- const sortedOptions = sortAccountsByQuery(options, searchQuery, queryKey);
128
- setItems(sortedOptions);
129
- });
125
+ if (abortControllerRef.current) {
126
+ abortControllerRef.current.abort();
127
+ }
128
+ abortControllerRef.current = new AbortController();
129
+ const isAppending = !!afterCursor;
130
+ if (!isAppending) {
131
+ setIsFetching(true);
132
+ }
133
+ try {
134
+ const where = buildSearchAccountsWhere(searchQuery);
135
+ const queryKey = isNaN(searchQuery) ? 'name' : 'accountNumber';
136
+ const { data } = yield apolloClient.query({
137
+ query: SEARCH_ACCOUNTS,
138
+ variables: Object.assign(Object.assign({ where, first: pageSize }, (afterCursor ? { after: afterCursor } : {})), { orderBy: { Name: { order: 'ASC' } } }),
139
+ context: { fetchOptions: { signal: abortControllerRef.current.signal } },
140
+ });
141
+ const result = handleGraphQLSearchAccountsResponse(data);
142
+ const newItems = result.items.map((item) => ({
143
+ accountNumber: item.accountNumber,
144
+ name: item.name,
145
+ }));
146
+ const sortedItems = sortAccountsByQuery(newItems, searchQuery, queryKey);
147
+ if (isAppending) {
148
+ setItems((prev) => [...prev, ...sortedItems]);
149
+ }
150
+ else {
151
+ setItems(sortedItems);
152
+ }
153
+ setHasNextPage(result.hasNextPage);
154
+ setEndCursor(result.endCursor);
155
+ setCurrentSearchQuery(searchQuery);
156
+ }
157
+ catch (err) {
158
+ if ((err === null || err === void 0 ? void 0 : err.name) !== 'AbortError') {
159
+ console.error('Failed to search accounts via GraphQL', err);
160
+ setItems([]);
161
+ setHasNextPage(false);
162
+ setEndCursor('');
163
+ }
164
+ }
165
+ finally {
166
+ setIsFetching(false);
167
+ }
168
+ }), [apolloClient]);
169
+ const fetchAccountsRef = useRef(fetchAccounts);
170
+ fetchAccountsRef.current = fetchAccounts;
171
+ const debouncedFetchAccounts = useMemo(() => { var _a; return debounce((value) => fetchAccountsRef.current(value), (_a = props.delay) !== null && _a !== void 0 ? _a : 300); }, [props.delay]);
172
+ useEffect(() => {
173
+ return () => {
174
+ debouncedFetchAccounts.cancel();
175
+ };
176
+ }, [debouncedFetchAccounts]);
130
177
  const onOuterClick = () => {
131
178
  setQueryLabel(props.selectedAccounts || []);
132
179
  setSelectedItems(props.selectedAccounts || []);
@@ -162,15 +209,19 @@ function AccountSelectorInternal(props) {
162
209
  (_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
163
210
  };
164
211
  const onFilter = (_event, value) => {
165
- const trimmed = value.trim();
166
212
  setQuery(value);
167
- setIsQueryChanged(!isEmpty(trimmed));
168
- if (!isEmpty(trimmed)) {
169
- setIsOpen(true);
170
- }
171
- fetchAccounts(value);
172
- setResultSize(pageSize);
213
+ setIsQueryChanged(!isEmpty(value));
173
214
  setFocusedItemIndex(null);
215
+ if (isEmpty(value)) {
216
+ debouncedFetchAccounts.cancel();
217
+ setItems([]);
218
+ setIsFetching(false);
219
+ setHasNextPage(false);
220
+ setEndCursor('');
221
+ return;
222
+ }
223
+ setIsFetching(true);
224
+ debouncedFetchAccounts(value);
174
225
  };
175
226
  const onToggleClick = () => {
176
227
  setIsOpen((pre) => !pre);
@@ -186,6 +237,9 @@ function AccountSelectorInternal(props) {
186
237
  setSelectedItems([]);
187
238
  setItems([]);
188
239
  setIsQueryChanged(false);
240
+ setHasNextPage(false);
241
+ setEndCursor('');
242
+ setCurrentSearchQuery('');
189
243
  (_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
190
244
  };
191
245
  const onSelect = (selection) => {
@@ -242,7 +296,9 @@ function AccountSelectorInternal(props) {
242
296
  const toggle = (toggleRef) => (React.createElement(MenuToggle, { innerRef: toggleRef, variant: "typeahead", onClick: onToggleClick, isExpanded: isOpen, isFullWidth: true, isDisabled: props.disabled },
243
297
  React.createElement(TextInputGroup, { isPlain: true, innerRef: inputGroupRef },
244
298
  React.createElement(TextInputGroupMain, { value: query, role: "combobox", onClick: onInputClick, onKeyDown: onInputKeyDown, onChange: onFilter, placeholder: t(props.placeholder || ''), isExpanded: isOpen, innerRef: textInputRef, "aria-label": `select${props.multiple ? ' multi' : ''} typeahead listbox`, "aria-controls": "account-selector-dropdown" }),
245
- React.createElement(TextInputGroupUtilities, null, !isEmpty(query) && (React.createElement(Button, { icon: isFetching ? (React.createElement(LoadingIndicator, { show: true, size: "sm" })) : (React.createElement(TimesCircleIcon, { "aria-hidden": true })), variant: "plain", onClick: onClearSelection, isDisabled: isFetching, "aria-label": t('Clear') }))))));
299
+ React.createElement(TextInputGroupUtilities, null,
300
+ props.showSelectionCountBadge && props.multiple && selectedItems.length > 0 && (React.createElement(Badge, { className: "advance-search-dropdown-toggle-badge pf-v6-u-mr-sm" }, t('{{count}} selected', { count: selectedItems.length }))),
301
+ !isEmpty(query) && (React.createElement(Button, { icon: isFetching ? (React.createElement(LoadingIndicator, { show: true, size: "sm" })) : (React.createElement(TimesCircleIcon, { "aria-hidden": true })), variant: "plain", onClick: onClearSelection, isDisabled: isFetching, "aria-label": t('Clear') }))))));
246
302
  return (React.createElement(Select, { "data-tracking-id": "account-selector-dropdown", isOpen: isOpen, onOpenChange: () => setIsOpen(false), id: props.id, toggle: toggle, popperProps: { direction: 'down', enableFlip: false }, onSelect: (_e, v) => onSelect(v), selected: selectedItems, isScrollable: true },
247
303
  React.createElement(SelectList, null, dropdownOptions)));
248
304
  }
@@ -1,4 +1,10 @@
1
1
  import './embeddedServiceChat.css';
2
2
  import { FC } from 'react';
3
+ /**
4
+ * Bootstraps Salesforce Enhanced Messaging.
5
+ * The messaging widget (button + chat window) is rendered by the Salesforce
6
+ * bootstrap script; this component only triggers initialisation and shows a
7
+ * spinner while the script loads.
8
+ */
3
9
  export declare const EmbeddedServiceChat: FC;
4
10
  //# sourceMappingURL=EmbeddedServiceChat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmbeddedServiceChat.d.ts","sourceRoot":"","sources":["../../../../src/components/EmbeddedServiceChat/EmbeddedServiceChat.tsx"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AAInC,OAAc,EAAE,EAAE,EAAoB,MAAM,OAAO,CAAC;AAMpD,eAAO,MAAM,mBAAmB,EAAE,EA6HjC,CAAC"}
1
+ {"version":3,"file":"EmbeddedServiceChat.d.ts","sourceRoot":"","sources":["../../../../src/components/EmbeddedServiceChat/EmbeddedServiceChat.tsx"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AAGnC,OAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKlC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAcjC,CAAC"}
@@ -1,55 +1,21 @@
1
1
  import './embeddedServiceChat.css';
2
- import { Button, ButtonVariant, Popover, PopoverPosition, Spinner } from '@patternfly/react-core';
3
- import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
4
- import React, { useRef, useState } from 'react';
5
- import { Trans, useTranslation } from 'react-i18next';
6
- import { FeatureAnnouncementKeys, NewFeaturePopoverAnnouncement, useChatInit } from '../..';
7
- import { ChatSVGIcon } from './ChatSVGIcon';
2
+ import { Spinner } from '@patternfly/react-core';
3
+ import React from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { useChatInit } from '../../hooks/useChatInit';
6
+ /**
7
+ * Bootstraps Salesforce Enhanced Messaging.
8
+ * The messaging widget (button + chat window) is rendered by the Salesforce
9
+ * bootstrap script; this component only triggers initialisation and shows a
10
+ * spinner while the script loads.
11
+ */
8
12
  export const EmbeddedServiceChat = () => {
9
- var _a;
10
- const componentRef = useRef(null);
11
- const { loadingChat, isChatStarted, onStartChat, hasChatDomainsBlocked, hasBlockedByBrowser, chatServiceNotAvailable, hasBlockedByCookie, getChatFormDetails, } = useChatInit();
12
- const [isBlockedErrorBoxVisible, setIsBlockedErrorBoxVisible] = useState(true);
13
- const [chatClicked, setChatClicked] = useState(false);
14
- const { t } = useTranslation();
15
- const sessionId = (_a = getChatFormDetails().find((item) => item.label === 'SessionId')) === null || _a === void 0 ? void 0 : _a.value;
16
- const shouldClose = () => {
17
- setIsBlockedErrorBoxVisible(false);
18
- };
19
- const shouldOpen = () => {
20
- setIsBlockedErrorBoxVisible(true);
21
- };
22
- const chatErrorMessagePopover = (param) => (React.createElement("div", { className: "chatButton chatError", id: "chat-blocked-popover-selector" },
23
- React.createElement(Popover, { "aria-label": t('Cannot connect to chat support'), alertSeverityVariant: 'danger', position: PopoverPosition.top, hasAutoWidth: true, maxWidth: '420px', headerIcon: React.createElement(ExclamationCircleIcon, { className: "pf-v6-u-danger-color-100" }), headerComponent: "h1", headerContent: React.createElement(Trans, null, "Cannot connect to chat support"), bodyContent: param === 'cookie' ? (React.createElement("p", { className: "pf-v6-u-px-md" },
24
- React.createElement(Trans, null,
25
- "Accept functional cookies in your",
26
- ' ',
27
- React.createElement(Button, { variant: ButtonVariant.link, isInline: true, onClick: (e) => {
28
- e.preventDefault();
29
- document.querySelector('#teconsent a[role="link"]').click();
30
- } }, "cookie preferences"),
31
- ' ',
32
- "to enable the Red Hat Chat Support, then refresh page."))) : (React.createElement("p", { className: "pf-v6-u-px-md" },
33
- React.createElement(Trans, null, "There are multiple problems that can cause this error."),
34
- React.createElement("br", null),
35
- React.createElement("a", { href: `https://access.redhat.com/articles/313583#${hasBlockedByBrowser
36
- ? 'troubleshoot_browser'
37
- : hasChatDomainsBlocked
38
- ? 'troubleshoot_network'
39
- : ''}`, target: "_blank", rel: "noreferrer noopener" },
40
- React.createElement(Trans, null, "See a list of possible causes.")))), isVisible: isBlockedErrorBoxVisible, shouldClose: shouldClose, shouldOpen: shouldOpen },
41
- React.createElement(Button, { variant: ButtonVariant.link, className: "pf-v6-u-m-0 pf-v6-u-p-0" },
42
- React.createElement(ChatSVGIcon, null)))));
43
- if (chatServiceNotAvailable)
13
+ const { loadingChat, chatServiceNotAvailable, hasBlockedByCookie } = useChatInit();
14
+ if (chatServiceNotAvailable || hasBlockedByCookie)
44
15
  return React.createElement(React.Fragment, null);
45
- return loadingChat ? (React.createElement("div", { className: "chatButton" },
46
- React.createElement(Spinner, { diameter: "28px", className: "pf-v6-u-m-xs" }))) : hasBlockedByCookie && chatClicked && document.querySelector('#teconsent a[role="link"]') !== null ? (chatErrorMessagePopover('cookie')) : (hasBlockedByBrowser || hasChatDomainsBlocked || !sessionId) && chatClicked ? (chatErrorMessagePopover()) : !isChatStarted ? (React.createElement("div", { className: "chatButton", onClick: () => {
47
- setChatClicked(true);
48
- if (sessionId) {
49
- onStartChat();
50
- }
51
- }, "data-tracking-id": "embedded-service-chat", ref: componentRef, id: "chat-bot-wrapper" },
52
- React.createElement(ChatSVGIcon, null),
53
- React.createElement(NewFeaturePopoverAnnouncement, { "aria-label": t('Support now has a chatbot (beta). Try it if you need help with a case.'), featureName: FeatureAnnouncementKeys.CHAT_BOT, sectionRef: componentRef, bodyContent: React.createElement("div", null,
54
- React.createElement(Trans, null, "Support now has a chatbot (beta). Try it if you need help with a case.")), triggerRef: () => document.getElementById('chat-bot-wrapper') }))) : (React.createElement(React.Fragment, null));
16
+ if (loadingChat) {
17
+ return createPortal(React.createElement("div", { className: "chatButton" },
18
+ React.createElement(Spinner, { diameter: "28px", className: "pf-v6-u-m-xs" })), document.body);
19
+ }
20
+ return React.createElement(React.Fragment, null);
55
21
  };
@@ -3,6 +3,7 @@
3
3
  position: fixed;
4
4
  right: 4rem;
5
5
  bottom: 1rem;
6
+ z-index: var(--pf-t--global--z-index--2xl, 200);
6
7
  width: 48px;
7
8
  height: 48px;
8
9
  padding: var(--global-spacer-sm, 8px);
@@ -18,54 +19,3 @@
18
19
  body:has(.pf-chatbot) .chatButton {
19
20
  display: none !important;
20
21
  }
21
-
22
- .chatError {
23
- opacity: 0.7;
24
- }
25
-
26
- /* Requested by CCM team */
27
- .agent .chat-content[CLWCP-lwcchatpack_lwcchatpack] {
28
- text-align: left;
29
- }
30
-
31
- /* Adding fowling CSS as requested by CCM team (Sudhir Panda) */
32
- .embeddedServiceLiveAgentStateChat .chatSessionStartTime {
33
- font-family: 'Red Hat Text', 'RedHatText', 'Overpass', Overpass, Arial, sans-serif;
34
- }
35
- .embeddedServiceLiveAgentStateChatItem.chatMessage {
36
- font-family: 'Red Hat Text', 'RedHatText', 'Overpass', Overpass, Arial, sans-serif;
37
- }
38
- .embeddedServiceLiveAgentStateChatItem.chatMessage button {
39
- font-family: 'Red Hat Text', 'RedHatText', 'Overpass', Overpass, Arial, sans-serif;
40
- }
41
- .embeddedServiceHelpButton .helpButton .uiButton {
42
- background-color: #005290;
43
- font-family: 'Arial', sans-serif;
44
- }
45
- .embeddedServiceHelpButton .helpButton .uiButton:focus {
46
- outline: 1px solid #005290;
47
- }
48
- .agent .chat-content[CLWCP-lwcchatpack_lwcchatpack] {
49
- text-align: left;
50
- font-family: 'Red Hat Text', 'RedHatText', 'Overpass', Overpass, Arial, sans-serif;
51
- }
52
- /* red hat chat icon */
53
- .embeddedServiceLiveAgentStateChatAvatar.isLightningOutContext .agentIconColor0 {
54
- background-image: url('https://access.redhat.com/chrome_themes/nimbus/img/red-hat-customer-portal.svg');
55
- background-repeat: no-repeat;
56
- background-size: 420% !important;
57
- font-size: 0 !important;
58
- background-color: #fff !important;
59
- }
60
-
61
- /* user chat bubble */
62
- .chasitor.chat-content[CLWCP-lwcchatpack_lwcchatpack] {
63
- background: #fff !important;
64
- color: #0066cc !important;
65
- border: #0066cc 1px solid !important;
66
- }
67
-
68
- /* timeout text background color */
69
- .embeddedServiceSidebar .headerAnnouncement p {
70
- background-color: #151515;
71
- }
@@ -1 +1 @@
1
- {"version":3,"file":"CSSUserModal.d.ts","sourceRoot":"","sources":["../../../../src/components/SharedModals/CSSUserModal.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AAIpD,UAAU,MAAM;IACZ,oCAAoC,EAAE,MAAM,IAAI,CAAC;IACjD,OAAO,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,oCAAoC,EAAE,OAAO,EAAE,EAAE,MAAM,qBAiGrF"}
1
+ {"version":3,"file":"CSSUserModal.d.ts","sourceRoot":"","sources":["../../../../src/components/SharedModals/CSSUserModal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA+B,MAAM,OAAO,CAAC;AAIpD,UAAU,MAAM;IACZ,oCAAoC,EAAE,MAAM,IAAI,CAAC;IACjD,OAAO,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,oCAAoC,EAAE,OAAO,EAAE,EAAE,MAAM,qBAiGrF"}
@@ -1,4 +1,5 @@
1
1
  import { Button, Modal, ModalBody, ModalFooter, ModalHeader, ModalVariant } from '@patternfly/react-core';
2
+ import { getCssPortalUrl } from '@rh-support/utils';
2
3
  import React, { useContext, useState } from 'react';
3
4
  import { GlobalMetadataStateContext } from '../../context/GlobalMetadataContext';
4
5
  export function CSSUserModal({ onConfirmTraditionalSupportAgreement, display }) {
@@ -8,7 +9,7 @@ export function CSSUserModal({ onConfirmTraditionalSupportAgreement, display })
8
9
  const { globalMetadataState: { loggedInUsersAccount }, } = useContext(GlobalMetadataStateContext);
9
10
  const isConfirmedStateSideSupport = (_a = loggedInUsersAccount === null || loggedInUsersAccount === void 0 ? void 0 : loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.hasConfirmedStatesideSupport;
10
11
  const handleCSSclick = () => {
11
- window.open('https://govsupport.redhat.com/css/s/', '_self');
12
+ window.open(getCssPortalUrl(), '_self');
12
13
  };
13
14
  const handleTraditionalSupportClick = () => {
14
15
  setShowTraditionalSupportAgreement(true);
@@ -1,10 +1,10 @@
1
1
  import './CloseCaseModal.scss';
2
2
  import React from 'react';
3
3
  interface IProps {
4
- onConfirm: (commentBody: string) => void;
4
+ onConfirm: (commentBody: string) => Promise<boolean> | boolean;
5
5
  onClose: () => void;
6
6
  caseNumber?: string;
7
- isUpdating: boolean;
7
+ isUpdating?: boolean;
8
8
  }
9
9
  export declare function CloseCaseModal(props: IProps): React.JSX.Element;
10
10
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"CloseCaseModal.d.ts","sourceRoot":"","sources":["../../../../src/components/SharedModals/CloseCaseModal.tsx"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAoB/B,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,UAAU,MAAM;IACZ,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACvB;AAUD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,qBAkL3C"}
1
+ {"version":3,"file":"CloseCaseModal.d.ts","sourceRoot":"","sources":["../../../../src/components/SharedModals/CloseCaseModal.tsx"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAoB/B,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,UAAU,MAAM;IACZ,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC/D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAUD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,qBAkM3C"}
@@ -24,17 +24,24 @@ const resolutionOptions = [...resolutionWithoutDescription, ...resolutionsWithDe
24
24
  export function CloseCaseModal(props) {
25
25
  const { t } = useTranslation();
26
26
  const [showTextArea, setShowTextArea] = useState(false);
27
+ const [isSubmitting, setIsSubmitting] = useState(false);
27
28
  const [selectedResolution, setSelectedResolution] = useState('');
28
29
  const [resolutionDescription, setResolutionDescription] = useState('');
29
30
  const [showValidationError, setShowValidationError] = useState(false);
30
31
  const isCaseListPage = !props.caseNumber;
32
+ const isBusy = isSubmitting || !!props.isUpdating;
33
+ const handleClose = () => {
34
+ if (!isBusy) {
35
+ props.onClose();
36
+ }
37
+ };
31
38
  const onResolutionChange = (option) => {
32
39
  setSelectedResolution(option.value);
33
40
  setShowValidationError(false);
34
41
  resolutionsWithDescription.includes(option.value) ? setShowTextArea(true) : setShowTextArea(false);
35
42
  };
36
43
  const getCommentBody = () => {
37
- return `**Reason for closing case:** \n${selectedResolution}${resolutionsWithDescription.includes(selectedResolution) ? `. ${resolutionDescription}` : ''}`;
44
+ return `<p><strong>Reason for closing case:</strong></p><p>${selectedResolution}${resolutionsWithDescription.includes(selectedResolution) ? `. ${resolutionDescription}` : ''}</p>`;
38
45
  };
39
46
  // To check for required fields
40
47
  const checkForRequiredFields = () => {
@@ -52,7 +59,16 @@ export function CloseCaseModal(props) {
52
59
  const onSubmit = () => __awaiter(this, void 0, void 0, function* () {
53
60
  if (!checkForRequiredFields())
54
61
  return;
55
- props.onConfirm(getCommentBody());
62
+ setIsSubmitting(true);
63
+ try {
64
+ const result = yield props.onConfirm(getCommentBody());
65
+ if (result) {
66
+ props.onClose();
67
+ }
68
+ }
69
+ finally {
70
+ setIsSubmitting(false);
71
+ }
56
72
  });
57
73
  const onDescriptionChange = (description) => {
58
74
  setShowValidationError(false);
@@ -67,7 +83,7 @@ export function CloseCaseModal(props) {
67
83
  label: t(selectedResolution),
68
84
  value: t(selectedResolution),
69
85
  };
70
- return (React.createElement(Modal, { id: "case-close-modal", "aria-describedby": "case-close-modal", isOpen: true, onClose: props.onClose, variant: ModalVariant.medium },
86
+ return (React.createElement(Modal, { id: "case-close-modal", "aria-describedby": "case-close-modal", isOpen: true, onClose: handleClose, variant: ModalVariant.medium },
71
87
  React.createElement(ModalHeader, null,
72
88
  React.createElement("h2", null,
73
89
  isCaseListPage && React.createElement(Trans, null, "Do you want to close the selected cases?"),
@@ -93,12 +109,12 @@ export function CloseCaseModal(props) {
93
109
  React.createElement(Trans, null, "All of the selected cases will have the same resolution in bulk edit."))),
94
110
  showValidationError && !selectedResolution && (React.createElement(HelperTextItem, { variant: "error" },
95
111
  React.createElement(Trans, null, "Required field"))))),
96
- React.createElement(SingleSelectDropdown, { placeholder: t('Select an option that best fits'), dataTrackingId: "case-resolution", options: getDropdownOptions, selected: getSelectedDropdownOption, isDisabled: props.isUpdating, isInvalid: showValidationError && !selectedResolution, onSelect: onResolutionChange })),
112
+ React.createElement(SingleSelectDropdown, { placeholder: t('Select an option that best fits'), dataTrackingId: "case-resolution", options: getDropdownOptions, selected: getSelectedDropdownOption, isDisabled: isBusy, isInvalid: showValidationError && !selectedResolution, onSelect: onResolutionChange })),
97
113
  showTextArea && (React.createElement(FormGroup, { label: t('Please describe your resolution'), type: "text", isRequired: true, fieldId: "close-case-description" },
98
- React.createElement(TextArea, { validated: showValidationError && !resolutionDescription ? 'error' : 'default', isRequired: true, id: "close-case-description", name: "close-case-description", "aria-describedby": "close-case-description", value: resolutionDescription, placeholder: t('Please describe your resolution to help us better understand.'), onChange: (_event, description) => onDescriptionChange(description), isDisabled: props.isUpdating, resizeOrientation: "vertical" }))))),
114
+ React.createElement(TextArea, { validated: showValidationError && !resolutionDescription ? 'error' : 'default', isRequired: true, id: "close-case-description", name: "close-case-description", "aria-describedby": "close-case-description", value: resolutionDescription, placeholder: t('Please describe your resolution to help us better understand.'), onChange: (_event, description) => onDescriptionChange(description), isDisabled: isBusy, resizeOrientation: "vertical" }))))),
99
115
  React.createElement(ModalFooter, null,
100
- React.createElement(Button, { key: "submit-description", variant: ButtonVariant.primary, onClick: onSubmit, isLoading: props.isUpdating, isDisabled: isResolutionDescEmpty || showValidationError || props.isUpdating, "data-tracking-id": "close-case-description-modal-submit" },
116
+ React.createElement(Button, { key: "submit-description", variant: ButtonVariant.primary, onClick: onSubmit, isLoading: isBusy, isDisabled: isResolutionDescEmpty || showValidationError || isBusy, "data-tracking-id": "close-case-description-modal-submit" },
101
117
  React.createElement(Trans, null, "Close case")),
102
- React.createElement(Button, { key: "close-modal", variant: ButtonVariant.secondary, onClick: props.onClose, isDisabled: props.isUpdating, "data-tracking-id": "close-case-description-modal-cancel" },
118
+ React.createElement(Button, { key: "close-modal", variant: ButtonVariant.secondary, onClick: handleClose, isDisabled: isBusy, "data-tracking-id": "close-case-description-modal-cancel" },
103
119
  React.createElement(Trans, null, "Cancel")))));
104
120
  }
@@ -0,0 +1,9 @@
1
+ import React, { ReactNode } from 'react';
2
+ export declare const CaseStatusContext: React.Context<string>;
3
+ interface CaseStatusProviderProps {
4
+ caseStatus?: string;
5
+ children: ReactNode;
6
+ }
7
+ export declare function CaseStatusProvider({ caseStatus, children }: CaseStatusProviderProps): React.JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=CaseStatusContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CaseStatusContext.d.ts","sourceRoot":"","sources":["../../../src/context/CaseStatusContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAExD,eAAO,MAAM,iBAAiB,uBAA+C,CAAC;AAE9E,UAAU,uBAAuB;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,uBAAuB,qBAEnF"}
@@ -0,0 +1,5 @@
1
+ import React, { createContext } from 'react';
2
+ export const CaseStatusContext = createContext(undefined);
3
+ export function CaseStatusProvider({ caseStatus, children }) {
4
+ return React.createElement(CaseStatusContext.Provider, { value: caseStatus }, children);
5
+ }