@rh-support/react-context 2.4.10-beta.6 → 2.5.1
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/README.md +0 -2
- package/lib/esm/GlobalContextWrapper.d.ts +2 -3
- package/lib/esm/GlobalContextWrapper.d.ts.map +1 -1
- package/lib/esm/GlobalContextWrapper.js +4 -1
- package/lib/esm/components/AccountSelector/AccountSelectorInternal.d.ts +2 -1
- package/lib/esm/components/AccountSelector/AccountSelectorInternal.d.ts.map +1 -1
- package/lib/esm/components/AccountSelector/AccountSelectorInternal.js +180 -95
- package/lib/esm/components/EmbeddedServiceChat/ChatSVGIcon.d.ts +2 -1
- package/lib/esm/components/EmbeddedServiceChat/ChatSVGIcon.d.ts.map +1 -1
- package/lib/esm/components/EmbeddedServiceChat/EmbeddedServiceChat.js +4 -4
- package/lib/esm/components/HostnameAwarenessModal/HostnameAwarenessModal.d.ts +2 -1
- package/lib/esm/components/HostnameAwarenessModal/HostnameAwarenessModal.d.ts.map +1 -1
- package/lib/esm/components/HostnameAwarenessModal/HostnameAwarenessModal.js +43 -48
- package/lib/esm/components/HostnameAwarenessModal/hostnameAwarenessModal.css +1 -1
- package/lib/esm/components/NewFeatureAnnouncement/NewFeatureLabel.d.ts +2 -1
- package/lib/esm/components/NewFeatureAnnouncement/NewFeatureLabel.d.ts.map +1 -1
- package/lib/esm/components/NewFeatureAnnouncement/NewFeatureLabel.js +1 -1
- package/lib/esm/components/NewFeatureAnnouncement/NewFeaturePopoverAnnouncement.d.ts +1 -1
- package/lib/esm/components/NewFeatureAnnouncement/NewFeaturePopoverAnnouncement.d.ts.map +1 -1
- package/lib/esm/components/SharedModals/CSSUserModal.d.ts +8 -0
- package/lib/esm/components/SharedModals/CSSUserModal.d.ts.map +1 -0
- package/lib/esm/components/SharedModals/CSSUserModal.js +34 -0
- package/lib/esm/components/SharedModals/CloseCaseModal.d.ts +2 -1
- package/lib/esm/components/SharedModals/CloseCaseModal.d.ts.map +1 -1
- package/lib/esm/components/SharedModals/CloseCaseModal.js +12 -6
- package/lib/esm/components/SharedModals/CloseCaseModal.scss +6 -6
- package/lib/esm/components/SharedModals/index.d.ts +1 -0
- package/lib/esm/components/SharedModals/index.d.ts.map +1 -1
- package/lib/esm/components/SharedModals/index.js +1 -0
- package/lib/esm/components/index.d.ts +0 -1
- package/lib/esm/components/index.d.ts.map +1 -1
- package/lib/esm/components/index.js +0 -1
- package/lib/esm/context/GlobalAlertMessageContext.d.ts +1 -1
- package/lib/esm/context/GlobalAlertMessageContext.d.ts.map +1 -1
- package/lib/esm/context/GlobalMetadataContext.d.ts +1 -1
- package/lib/esm/context/GlobalMetadataContext.d.ts.map +1 -1
- package/lib/esm/context/GlobalTranslationProvider.d.ts +1 -1
- package/lib/esm/context/GlobalTranslationProvider.d.ts.map +1 -1
- package/lib/esm/context/GlobalTranslationProvider.js +0 -1
- package/lib/esm/hooks/useChatConfig.js +9 -9
- package/lib/esm/hooks/useFeatureAnnouncement.d.ts.map +1 -1
- package/lib/esm/hooks/useFeatureAnnouncement.js +2 -2
- package/lib/esm/hooks/useUserPreferences.d.ts +19 -18
- package/lib/esm/hooks/useUserPreferences.d.ts.map +1 -1
- package/lib/esm/hooks/useUserPreferences.js +0 -1
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/reducers/GlobalAlertMessageReducer.d.ts +2 -2
- package/lib/esm/reducers/GlobalAlertMessageReducer.d.ts.map +1 -1
- package/lib/esm/reducers/GlobalMetadataReducer.d.ts +15 -9
- package/lib/esm/reducers/GlobalMetadataReducer.d.ts.map +1 -1
- package/lib/esm/reducers/GlobalMetadataReducer.js +34 -12
- package/lib/esm/utils/index.d.ts +5 -0
- package/lib/esm/utils/index.d.ts.map +1 -0
- package/lib/esm/utils/index.js +21 -0
- package/package.json +36 -28
- package/lib/esm/components/bookmarks/BookmarkedAccountsDropdown.d.ts +0 -15
- package/lib/esm/components/bookmarks/BookmarkedAccountsDropdown.d.ts.map +0 -1
- package/lib/esm/components/bookmarks/BookmarkedAccountsDropdown.js +0 -35
- package/lib/esm/components/bookmarks/index.d.ts +0 -2
- package/lib/esm/components/bookmarks/index.d.ts.map +0 -1
- package/lib/esm/components/bookmarks/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
interface IProps {
|
|
2
3
|
children: JSX.Element | JSX.Element[];
|
|
3
4
|
}
|
|
@@ -5,10 +6,8 @@ declare global {
|
|
|
5
6
|
interface Window {
|
|
6
7
|
sessionjs: any;
|
|
7
8
|
MSInputMethodContext: any;
|
|
8
|
-
chrometwo_require: (component: string[], callback: (...params: any[]) => any) => any;
|
|
9
9
|
portal: any;
|
|
10
10
|
Raven: any;
|
|
11
|
-
chrometwo_ready: any;
|
|
12
11
|
embedded_svc: any;
|
|
13
12
|
$Lightning: any;
|
|
14
13
|
liveAgentDeployment: any;
|
|
@@ -17,6 +16,6 @@ declare global {
|
|
|
17
16
|
documentMode: any;
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
|
-
export declare const GlobalContextWrapper: (props: IProps) => JSX.Element;
|
|
19
|
+
export declare const GlobalContextWrapper: (props: IProps) => React.JSX.Element;
|
|
21
20
|
export {};
|
|
22
21
|
//# sourceMappingURL=GlobalContextWrapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GlobalContextWrapper.d.ts","sourceRoot":"","sources":["../../src/GlobalContextWrapper.tsx"],"names":[],"mappings":"
|
|
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;AAkGD,eAAO,MAAM,oBAAoB,UAAW,MAAM,sBAKjD,CAAC"}
|
|
@@ -20,7 +20,9 @@ function GlobalContextMetadataWrapper() {
|
|
|
20
20
|
const dispatchToGlobalMetadataReducer = React.useContext(GlobalMetadataDispatchContext);
|
|
21
21
|
// Configuring callbacks to show modals in case of auth logout or session expiry
|
|
22
22
|
useEffect(() => {
|
|
23
|
-
|
|
23
|
+
const init = () => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
/** @type { import("@rhcp/primer") } */
|
|
25
|
+
const { session } = yield window.portal.primer.onReady();
|
|
24
26
|
session.on('AuthLogout', () => setShowReLoginModal(true));
|
|
25
27
|
['AuthRefreshError', 'TokenExpired'].forEach((eventName) => session.on(eventName, () => {
|
|
26
28
|
if (!session.isAuthenticated()) {
|
|
@@ -28,6 +30,7 @@ function GlobalContextMetadataWrapper() {
|
|
|
28
30
|
}
|
|
29
31
|
}));
|
|
30
32
|
});
|
|
33
|
+
init();
|
|
31
34
|
}, []);
|
|
32
35
|
const loadGlobalMetadata = (loggedInUserJwtToken) => {
|
|
33
36
|
setLoggedInUserJwtToken(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IAccount } from '@cee-eng/hydrajs/@types/models/account';
|
|
2
2
|
import { IAccountListParams } from '@cee-eng/hydrajs/@types/models/csp/account';
|
|
3
3
|
import { AsyncDropdownProps } from '@rh-support/components';
|
|
4
|
+
import React from 'react';
|
|
4
5
|
interface IProps extends AsyncDropdownProps<IAccount> {
|
|
5
6
|
selectedAccounts?: IAccount[];
|
|
6
7
|
excludeAccounts?: IAccount[];
|
|
@@ -13,7 +14,7 @@ interface IProps extends AsyncDropdownProps<IAccount> {
|
|
|
13
14
|
isInValid?: boolean;
|
|
14
15
|
restrictedOnSubscriptionAbuse?: boolean;
|
|
15
16
|
}
|
|
16
|
-
declare function AccountSelectorInternal(props: IProps): JSX.Element;
|
|
17
|
+
declare function AccountSelectorInternal(props: IProps): React.JSX.Element;
|
|
17
18
|
declare namespace AccountSelectorInternal {
|
|
18
19
|
var defaultProps: Partial<IProps>;
|
|
19
20
|
}
|
|
@@ -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;
|
|
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;AAgBhF,OAAO,EAAE,kBAAkB,EAA8B,MAAM,wBAAwB,CAAC;AAKxF,OAAO,KAA+C,MAAM,OAAO,CAAC;AAKpE,UAAU,MAAO,SAAQ,kBAAkB,CAAC,QAAQ,CAAC;IACjD,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;CAC3C;AAkCD,iBAAS,uBAAuB,CAAC,KAAK,EAAE,MAAM,qBAyS7C;kBAzSQ,uBAAuB;;;AA4ShC,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -8,14 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { accounts } from '@cee-eng/hydrajs';
|
|
11
|
+
import { Button, Flex, FlexItem, MenuToggle, Select, SelectList, SelectOption, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
|
|
11
12
|
import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import assign from 'lodash/assign';
|
|
13
|
+
import TimesCircleIcon from '@patternfly/react-icons/dist/js/icons/times-circle-icon';
|
|
14
|
+
import { LoadingIndicator, useFetch } from '@rh-support/components';
|
|
15
15
|
import isEmpty from 'lodash/isEmpty';
|
|
16
|
+
import isNull from 'lodash/isNull';
|
|
17
|
+
import isUndefined from 'lodash/isUndefined';
|
|
16
18
|
import uniqBy from 'lodash/uniqBy';
|
|
17
|
-
import React, { useEffect, useMemo, useState } from 'react';
|
|
19
|
+
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
18
20
|
import { Trans, useTranslation } from 'react-i18next';
|
|
21
|
+
import { sortAccountsByQuery } from '../../utils';
|
|
19
22
|
const defaultProps = {
|
|
20
23
|
id: '',
|
|
21
24
|
className: '',
|
|
@@ -36,48 +39,84 @@ const defaultProps = {
|
|
|
36
39
|
isInValid: false,
|
|
37
40
|
restrictedOnSubscriptionAbuse: false,
|
|
38
41
|
};
|
|
42
|
+
const getDisplayName = (account) => {
|
|
43
|
+
if (!account) {
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
return account.accountNumber
|
|
47
|
+
? account.name
|
|
48
|
+
? `${account.name} (${account.accountNumber})`
|
|
49
|
+
: account.accountNumber
|
|
50
|
+
: '';
|
|
51
|
+
};
|
|
39
52
|
function AccountSelectorInternal(props) {
|
|
40
53
|
const { request, isFetching } = useFetch(accounts.getAccounts, { isAbortable: true });
|
|
41
54
|
const [items, setItems] = useState([]);
|
|
42
55
|
const [selectedItems, setSelectedItems] = useState([]);
|
|
56
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
57
|
+
const [isQueryChanged, setIsQueryChanged] = useState(false);
|
|
58
|
+
const [query, setQuery] = useState('');
|
|
59
|
+
const [focusedItemIndex, setFocusedItemIndex] = useState(null);
|
|
60
|
+
const textInputRef = useRef();
|
|
61
|
+
const inputGroupRef = useRef();
|
|
43
62
|
const { t } = useTranslation();
|
|
44
63
|
const bookmarkedAccountsDeduped = uniqBy(props.bookmarkedAccounts, (b) => b.accountNumber);
|
|
64
|
+
const pageSize = 20;
|
|
65
|
+
const [resultSize, setResultSize] = useState(pageSize);
|
|
66
|
+
const setQueryLabel = (selectedItems) => {
|
|
67
|
+
const item = !isEmpty(selectedItems) && !props.multiple ? selectedItems[0] : {};
|
|
68
|
+
setQuery(getDisplayName(item));
|
|
69
|
+
};
|
|
70
|
+
const itemsToRender = useMemo(() => (isEmpty(items) ? bookmarkedAccountsDeduped : items.slice(0, props.paginate ? resultSize : items.length)), [items, bookmarkedAccountsDeduped, props.paginate, resultSize]);
|
|
45
71
|
useEffect(() => {
|
|
46
72
|
if (!props.multiple) {
|
|
47
73
|
const selectedItem = (props.selectedAccounts || [])[0];
|
|
48
|
-
selectedItem && selectedItem.accountNumber && setSelectedItems(props.selectedAccounts);
|
|
74
|
+
selectedItem && selectedItem.accountNumber && setSelectedItems(props.selectedAccounts || []);
|
|
49
75
|
}
|
|
50
76
|
else {
|
|
51
|
-
setSelectedItems(props.selectedAccounts);
|
|
77
|
+
setSelectedItems(props.selectedAccounts || []);
|
|
52
78
|
}
|
|
53
79
|
}, [props.selectedAccounts, props.multiple]);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: '';
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
setQueryLabel(selectedItems);
|
|
82
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
83
|
+
}, [selectedItems, props.multiple]);
|
|
84
|
+
const onDisplayMoreClick = (e) => {
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
setResultSize((pre) => Math.min(pre + pageSize, items.length));
|
|
87
|
+
setIsOpen(true);
|
|
63
88
|
};
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
return
|
|
89
|
+
const dropdownOptions = useMemo(() => {
|
|
90
|
+
if (isFetching) {
|
|
91
|
+
return (React.createElement("div", { key: "searching", className: "pf-v5-u-px-md pf-v5-u-py-sm" },
|
|
92
|
+
React.createElement(Trans, null, "Searching...")));
|
|
67
93
|
}
|
|
68
|
-
|
|
69
|
-
.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
React.createElement(
|
|
75
|
-
" ",
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
if (isQueryChanged && isEmpty(items)) {
|
|
95
|
+
return (React.createElement("div", { key: "no-results", className: "pf-v5-u-px-md pf-v5-u-py-sm" },
|
|
96
|
+
React.createElement(Trans, null, "No results found")));
|
|
97
|
+
}
|
|
98
|
+
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-v5-u-text-nowrap pf-v5-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
|
+
? [
|
|
107
|
+
React.createElement("div", { className: "pf-v5-c-divider", role: "separator", key: "separator" }),
|
|
108
|
+
React.createElement(SelectOption, { key: 'diplay-more-option', onClick: onDisplayMoreClick, value: 'display-more' },
|
|
109
|
+
React.createElement(Flex, { justifyContent: { default: 'justifyContentCenter' } },
|
|
110
|
+
React.createElement(FlexItem, { className: '"pf-v5-c-button pf-m-link pf-m-inline' },
|
|
111
|
+
React.createElement(Trans, null, "Display additional results")))),
|
|
112
|
+
]
|
|
113
|
+
: []),
|
|
114
|
+
];
|
|
115
|
+
},
|
|
116
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
117
|
+
[items, bookmarkedAccountsDeduped, isFetching, itemsToRender, isQueryChanged]);
|
|
79
118
|
const fetchAccounts = (query) => __awaiter(this, void 0, void 0, function* () {
|
|
80
|
-
if (query
|
|
119
|
+
if (isEmpty(query)) {
|
|
81
120
|
return;
|
|
82
121
|
}
|
|
83
122
|
const fields = ['accountNumber', 'accountId', 'name', 'subscriptionAbuse'].join(',');
|
|
@@ -87,86 +126,132 @@ function AccountSelectorInternal(props) {
|
|
|
87
126
|
limit: 60,
|
|
88
127
|
accountNumberNotNull: true,
|
|
89
128
|
};
|
|
129
|
+
let queryKey;
|
|
90
130
|
// query as number is a hack to get around TS, isNaN can take a string but it was throwing error here
|
|
91
131
|
if (isNaN(query)) {
|
|
92
132
|
params.nameLike = query;
|
|
133
|
+
queryKey = 'name';
|
|
93
134
|
}
|
|
94
135
|
else {
|
|
95
136
|
params.accountNumberLike = query;
|
|
137
|
+
queryKey = 'accountNumber';
|
|
96
138
|
}
|
|
97
|
-
const queryParams =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
setItems(options);
|
|
103
|
-
// setIsLoading(false);
|
|
139
|
+
const queryParams = params;
|
|
140
|
+
const response = request && (yield request(queryParams));
|
|
141
|
+
const options = response && response.items && response.items.length ? response.items : [];
|
|
142
|
+
const sortedOptions = sortAccountsByQuery(options, query, queryKey);
|
|
143
|
+
setItems(sortedOptions);
|
|
104
144
|
});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
145
|
+
const onOuterClick = () => {
|
|
146
|
+
setQueryLabel(props.selectedAccounts || []);
|
|
147
|
+
setSelectedItems(props.selectedAccounts || []);
|
|
148
|
+
};
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
const handleClickOutside = (event) => {
|
|
151
|
+
if (inputGroupRef.current && !inputGroupRef.current.contains(event.target)) {
|
|
152
|
+
onOuterClick();
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
156
|
+
return () => {
|
|
157
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
111
158
|
};
|
|
112
|
-
|
|
113
|
-
|
|
159
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
160
|
+
}, [selectedItems, props.selectedAccounts]);
|
|
161
|
+
const onMultiAccountSelection = (selection) => {
|
|
162
|
+
let list = [];
|
|
163
|
+
if (selectedItems.some((item) => item.accountNumber === selection.accountNumber)) {
|
|
164
|
+
list = selectedItems.filter((item) => item.accountNumber !== selection.accountNumber);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
list = [...props.selectedAccounts, selection];
|
|
168
|
+
}
|
|
169
|
+
setSelectedItems(list);
|
|
170
|
+
props.onSelect && props.onSelect(list);
|
|
114
171
|
};
|
|
115
|
-
const
|
|
116
|
-
|
|
172
|
+
const onSingleAccountSelection = (selection) => {
|
|
173
|
+
var _a;
|
|
174
|
+
setSelectedItems([selection]);
|
|
175
|
+
props.onSelect && props.onSelect([selection]);
|
|
176
|
+
setIsOpen(false);
|
|
177
|
+
(_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
178
|
+
};
|
|
179
|
+
const onFilter = (_event, value) => {
|
|
180
|
+
setQuery(value);
|
|
181
|
+
setIsQueryChanged(!isEmpty(value));
|
|
182
|
+
fetchAccounts(value);
|
|
183
|
+
setResultSize(pageSize);
|
|
184
|
+
setFocusedItemIndex(null);
|
|
185
|
+
};
|
|
186
|
+
const onToggleClick = () => {
|
|
187
|
+
setIsOpen((pre) => !pre);
|
|
117
188
|
};
|
|
118
|
-
const
|
|
189
|
+
const onClearSelection = (e) => {
|
|
190
|
+
var _a;
|
|
191
|
+
e.stopPropagation();
|
|
192
|
+
setIsOpen(true);
|
|
119
193
|
setSelectedItems([]);
|
|
194
|
+
setItems([]);
|
|
195
|
+
setIsQueryChanged(false);
|
|
196
|
+
(_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
120
197
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const memoizedBookmarkAccounts = useMemo(() => toOptions(getDropdownOptions(bookmarkedAccountsDeduped || []), {
|
|
126
|
-
labelKey: getDisplayName,
|
|
127
|
-
childrenKey: 'children',
|
|
128
|
-
actionItemKey: 'actionItem',
|
|
129
|
-
}),
|
|
130
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
131
|
-
[bookmarkedAccountsDeduped]);
|
|
132
|
-
const onMultiChange = (items) => {
|
|
133
|
-
const accounts = items.map((item) => ({
|
|
134
|
-
accountNumber: item.value.accountNumber,
|
|
135
|
-
name: item.value.name,
|
|
136
|
-
subscriptionAbuse: item.value.subscriptionAbuse,
|
|
137
|
-
}));
|
|
138
|
-
setSelectedItems(accounts);
|
|
139
|
-
props.onSelect && props.onSelect(accounts);
|
|
198
|
+
const onSelect = (selection) => {
|
|
199
|
+
if (selection === 'display-more' || isUndefined(selection) || isNull(selection))
|
|
200
|
+
return;
|
|
201
|
+
props.multiple ? onMultiAccountSelection(selection) : onSingleAccountSelection(selection);
|
|
140
202
|
};
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
203
|
+
const handleMenuArrowKeys = (key) => {
|
|
204
|
+
let indexToFocus;
|
|
205
|
+
if (isOpen) {
|
|
206
|
+
if (key === 'ArrowUp') {
|
|
207
|
+
// When no index is set or at the first index, focus to the last, otherwise decrement focus index
|
|
208
|
+
if (focusedItemIndex === null || focusedItemIndex === 0) {
|
|
209
|
+
indexToFocus = itemsToRender.length - 1;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
indexToFocus = focusedItemIndex - 1;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (key === 'ArrowDown') {
|
|
216
|
+
// When no index is set or at the last index, focus to the first, otherwise increment focus index
|
|
217
|
+
if (focusedItemIndex === null || focusedItemIndex === itemsToRender.length - 1) {
|
|
218
|
+
indexToFocus = 0;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
indexToFocus = focusedItemIndex + 1;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
setFocusedItemIndex(indexToFocus);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
const onInputKeyDown = (event) => {
|
|
228
|
+
const focusedItem = focusedItemIndex ? itemsToRender[focusedItemIndex] : itemsToRender[0];
|
|
229
|
+
switch (event.key) {
|
|
230
|
+
// Select the first available option
|
|
231
|
+
case 'Enter':
|
|
232
|
+
if (!isOpen) {
|
|
233
|
+
setIsOpen((pre) => !pre);
|
|
234
|
+
}
|
|
235
|
+
else if (isOpen) {
|
|
236
|
+
onSelect(focusedItem);
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
case 'Escape':
|
|
240
|
+
setIsOpen(false);
|
|
241
|
+
break;
|
|
242
|
+
case 'ArrowUp':
|
|
243
|
+
case 'ArrowDown':
|
|
244
|
+
event.preventDefault();
|
|
245
|
+
handleMenuArrowKeys(event.key);
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
168
248
|
};
|
|
169
|
-
|
|
249
|
+
const toggle = (toggleRef) => (React.createElement(MenuToggle, { innerRef: toggleRef, variant: "typeahead", onClick: onToggleClick, isExpanded: isOpen, isFullWidth: true, isDisabled: props.disabled },
|
|
250
|
+
React.createElement(TextInputGroup, { isPlain: true, innerRef: inputGroupRef },
|
|
251
|
+
React.createElement(TextInputGroupMain, { value: query, role: "combobox", onClick: onToggleClick, 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" }),
|
|
252
|
+
React.createElement(TextInputGroupUtilities, null, !isEmpty(query) && (React.createElement(Button, { variant: "plain", onClick: onClearSelection, isDisabled: isFetching, "aria-label": t('Clear') }, isFetching ? React.createElement(LoadingIndicator, { show: true, size: "sm" }) : React.createElement(TimesCircleIcon, { "aria-hidden": true })))))));
|
|
253
|
+
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 },
|
|
254
|
+
React.createElement(SelectList, null, dropdownOptions)));
|
|
170
255
|
}
|
|
171
256
|
AccountSelectorInternal.defaultProps = defaultProps;
|
|
172
257
|
export { AccountSelectorInternal };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatSVGIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/EmbeddedServiceChat/ChatSVGIcon.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChatSVGIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/EmbeddedServiceChat/ChatSVGIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,WAAW,yBAwBvB,CAAC"}
|
|
@@ -17,7 +17,7 @@ export const EmbeddedServiceChat = () => {
|
|
|
17
17
|
setIsBlockedErrorBoxVisible(true);
|
|
18
18
|
};
|
|
19
19
|
const chatErrorMessagePopover = () => (React.createElement("div", { className: "chatButton chatError", id: "chat-blocked-popover-selector" },
|
|
20
|
-
React.createElement(Popover, { "aria-label": t('Cannot connect to chat support'), alertSeverityVariant: 'danger', position: PopoverPosition.top, hasAutoWidth: true, headerIcon: React.createElement(ExclamationCircleIcon, { className: "pf-u-danger-color-100" }), headerComponent: "h1", headerContent: React.createElement(Trans, null, "Cannot connect to chat support"), bodyContent: React.createElement("p", { className: "pf-u-px-md" },
|
|
20
|
+
React.createElement(Popover, { "aria-label": t('Cannot connect to chat support'), alertSeverityVariant: 'danger', position: PopoverPosition.top, hasAutoWidth: true, headerIcon: React.createElement(ExclamationCircleIcon, { className: "pf-v5-u-danger-color-100" }), headerComponent: "h1", headerContent: React.createElement(Trans, null, "Cannot connect to chat support"), bodyContent: React.createElement("p", { className: "pf-v5-u-px-md" },
|
|
21
21
|
React.createElement(Trans, null, "There are multiple problems that can cause this error."),
|
|
22
22
|
React.createElement("br", null),
|
|
23
23
|
React.createElement("a", { href: `https://access.redhat.com/articles/313583#${hasBlockedByBrowser
|
|
@@ -26,7 +26,7 @@ export const EmbeddedServiceChat = () => {
|
|
|
26
26
|
? 'troubleshoot_network'
|
|
27
27
|
: ''}`, target: "_blank", rel: "noreferrer noopener" },
|
|
28
28
|
React.createElement(Trans, null, "See a list of possible causes."))), isVisible: isBlockedErrorBoxVisible, shouldClose: shouldClose, shouldOpen: shouldOpen },
|
|
29
|
-
React.createElement(Button, { variant: ButtonVariant.link, className: "pf-u-m-0 pf-u-p-0" },
|
|
29
|
+
React.createElement(Button, { variant: ButtonVariant.link, className: "pf-v5-u-m-0 pf-v5-u-p-0" },
|
|
30
30
|
React.createElement(ChatSVGIcon, null)))));
|
|
31
31
|
useEffect(() => {
|
|
32
32
|
initEmbedChat();
|
|
@@ -35,8 +35,8 @@ export const EmbeddedServiceChat = () => {
|
|
|
35
35
|
if (chatNotLoaded)
|
|
36
36
|
return React.createElement(React.Fragment, null);
|
|
37
37
|
return loadingChat ? (React.createElement("div", { className: "chatButton" },
|
|
38
|
-
React.createElement(Spinner, {
|
|
38
|
+
React.createElement(Spinner, { diameter: "28px", className: "pf-v5-u-m-xs" }))) : hasBlockedByBrowser || hasChatDomainsBlocked ? (chatErrorMessagePopover()) : !isChatStarted ? (React.createElement("div", { className: "chatButton", onClick: onStartChat, "data-tracking-id": "embedded-service-chat", ref: componentRef, id: "chat-bot-wrapper" },
|
|
39
39
|
React.createElement(ChatSVGIcon, null),
|
|
40
40
|
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,
|
|
41
|
-
React.createElement(Trans, null, "Support now has a chatbot (beta). Try it if you need help with a case.")),
|
|
41
|
+
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));
|
|
42
42
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HostnameAwarenessModal.d.ts","sourceRoot":"","sources":["../../../../src/components/HostnameAwarenessModal/HostnameAwarenessModal.tsx"],"names":[],"mappings":"AAAA,OAAO,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"HostnameAwarenessModal.d.ts","sourceRoot":"","sources":["../../../../src/components/HostnameAwarenessModal/HostnameAwarenessModal.tsx"],"names":[],"mappings":"AAAA,OAAO,8BAA8B,CAAC;AAOtC,OAAO,KAA0C,MAAM,OAAO,CAAC;AAO/D,eAAO,MAAM,sBAAsB,yBAsKlC,CAAC"}
|
|
@@ -17,56 +17,65 @@ import React, { useContext, useEffect, useState } from 'react';
|
|
|
17
17
|
import { Trans } from 'react-i18next';
|
|
18
18
|
import { GlobalMetadataDispatchContext, useGlobalStateContext } from '../../context/GlobalMetadataContext';
|
|
19
19
|
import { useUserPreferences } from '../../hooks';
|
|
20
|
-
import {
|
|
20
|
+
import { updateShareHostnameWithRHTState } from '../../reducers/GlobalMetadataReducer';
|
|
21
21
|
export const HostnameAwarenessModal = () => {
|
|
22
22
|
// Function to fetch original data
|
|
23
23
|
const { getHostnamesVisibilityObj, updateShowHostnamesCount } = useUserPreferences();
|
|
24
24
|
// Setting State for original data value which are used to open/finalize close modal
|
|
25
|
-
const [originalViewedCountValue, setViewedCountValue] = useState(
|
|
26
|
-
const [doNotShowModal, setDoNotShowModal] = useState(
|
|
27
|
-
const [
|
|
28
|
-
const [isModalOpen, setIsModalOpen] = useState(true);
|
|
25
|
+
const [originalViewedCountValue, setViewedCountValue] = useState(undefined);
|
|
26
|
+
const [doNotShowModal, setDoNotShowModal] = useState(0);
|
|
27
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
29
28
|
const [isHostnamesChecked, setisHostnamesChecked] = useState(false);
|
|
30
|
-
const
|
|
31
|
-
//preserving initial state to disable modal load
|
|
32
|
-
const [alreadyCheckedCloseModal, setAlreadyCheckedCloseModal] = useState(false);
|
|
33
|
-
const [isHostnamesLoading, setIsHostnamesLoading] = useState(true);
|
|
34
|
-
const { globalMetadataState: { loggedInUsersAccount, loggedInUserJwtToken }, } = useGlobalStateContext();
|
|
29
|
+
const { globalMetadataState: { loggedInUsersAccount }, } = useGlobalStateContext();
|
|
35
30
|
const dispatchToGlobalMetadataReducer = useContext(GlobalMetadataDispatchContext);
|
|
36
31
|
const accountNumber = loggedInUsersAccount.data.accountNumber;
|
|
37
32
|
const { request: updateHostnameDefault, isFetching: isFetchingUpdateHostnameDefault } = useFetch(accounts.updateIsSharingHostname);
|
|
33
|
+
//Do not show modal if user cannot share hostnames.
|
|
34
|
+
const canUseHostName = ability.can(resourceActions.PATCH, resources.CASE_CREATE, CaseListFields.HOSTNAME);
|
|
38
35
|
useEffect(() => {
|
|
36
|
+
if (loggedInUsersAccount.isFetching)
|
|
37
|
+
return;
|
|
38
|
+
let localOriginalViewedCountValue;
|
|
39
|
+
let localDoNotShowModal;
|
|
39
40
|
const userOriginalHostnamesCount = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
41
|
try {
|
|
41
|
-
setIsLoadingHostnamesVisibilityObj(true);
|
|
42
42
|
const originalHostnameVisibilityObj = yield getHostnamesVisibilityObj();
|
|
43
|
+
if (!originalHostnameVisibilityObj)
|
|
44
|
+
return;
|
|
43
45
|
const parsedVisibilityObj = JSON.parse(originalHostnameVisibilityObj);
|
|
44
|
-
|
|
46
|
+
// updating space takes time, here we define a lcal variable to immidiatly use the value
|
|
47
|
+
localOriginalViewedCountValue = parsedVisibilityObj.shownCount;
|
|
48
|
+
localDoNotShowModal = parsedVisibilityObj.doNotShow;
|
|
45
49
|
setViewedCountValue(parsedVisibilityObj.shownCount);
|
|
46
50
|
setDoNotShowModal(parsedVisibilityObj.doNotShow);
|
|
47
51
|
}
|
|
48
52
|
catch (error) {
|
|
49
|
-
setIsLoadingHostnamesVisibilityObj(false);
|
|
50
53
|
console.log(error);
|
|
51
54
|
}
|
|
52
55
|
});
|
|
53
56
|
const userOriginalHostnameValue = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
-
var _a
|
|
57
|
+
var _a;
|
|
55
58
|
setisHostnamesChecked((_a = loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.shareHostnameWithRHT);
|
|
56
|
-
// This is needed so we preserve initial state we do not close modal upon updating names.
|
|
57
|
-
setAlreadyCheckedCloseModal((_b = loggedInUsersAccount.data) === null || _b === void 0 ? void 0 : _b.shareHostnameWithRHT);
|
|
58
|
-
setIsHostnamesLoading(false);
|
|
59
59
|
});
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
const init = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
yield userOriginalHostnamesCount();
|
|
62
|
+
userOriginalHostnameValue();
|
|
63
|
+
//Do not show modal if user is already sharing hostnames, has seen the modal more than twice, or opted to not show it again
|
|
64
|
+
if (canUseHostName && localDoNotShowModal !== 1 && localOriginalViewedCountValue < 2) {
|
|
65
|
+
setIsModalOpen(true);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
init();
|
|
62
69
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
63
|
-
}, []);
|
|
70
|
+
}, [loggedInUsersAccount.isFetching]);
|
|
64
71
|
// To handle modal close
|
|
65
72
|
const onCloseModal = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
if (isFetchingUpdateHostnameDefault)
|
|
74
|
+
return;
|
|
66
75
|
try {
|
|
67
76
|
const updatedCountValue = (originalViewedCountValue || 0) + 1;
|
|
68
77
|
updateShowHostnamesCount({ shownCount: updatedCountValue, doNotShow: doNotShowModal });
|
|
69
|
-
setIsModalOpen(
|
|
78
|
+
setIsModalOpen(false);
|
|
70
79
|
}
|
|
71
80
|
catch (error) {
|
|
72
81
|
console.log(error);
|
|
@@ -75,21 +84,19 @@ export const HostnameAwarenessModal = () => {
|
|
|
75
84
|
// for hostnames swich
|
|
76
85
|
const onHostnameSwitchChange = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
86
|
try {
|
|
78
|
-
setIsHostnamesLoading(true);
|
|
79
87
|
yield updateHostnameDefault(!isHostnamesChecked, accountNumber);
|
|
80
|
-
|
|
88
|
+
// update state
|
|
89
|
+
updateShareHostnameWithRHTState(dispatchToGlobalMetadataReducer, loggedInUsersAccount.data, true);
|
|
81
90
|
setisHostnamesChecked(!isHostnamesChecked);
|
|
82
91
|
}
|
|
83
92
|
catch (error) {
|
|
84
93
|
console.log(error);
|
|
85
94
|
}
|
|
86
|
-
setIsHostnamesLoading(false);
|
|
87
95
|
});
|
|
88
96
|
//for the checkbox
|
|
89
97
|
const onDoNotAskAgain = () => {
|
|
90
98
|
try {
|
|
91
|
-
|
|
92
|
-
setDoNotShowModal(!doNotShowModal);
|
|
99
|
+
setDoNotShowModal(1);
|
|
93
100
|
const updateObjValue = { shownCount: originalViewedCountValue, doNotShow: 1 };
|
|
94
101
|
updateShowHostnamesCount(updateObjValue);
|
|
95
102
|
}
|
|
@@ -105,27 +112,15 @@ export const HostnameAwarenessModal = () => {
|
|
|
105
112
|
return (React.createElement(React.Fragment, null,
|
|
106
113
|
React.createElement(Switch, { label: "Share hostnames", isChecked: isHostnamesChecked, onChange: onHostnameSwitchChange, className: "push-top-narrow" }),
|
|
107
114
|
React.createElement(Tooltip, { content: shareHostnamesClarificationCopy, position: "right" },
|
|
108
|
-
React.createElement(InfoIcon, { className: "pf-u-ml-sm hostnameInfoIcon" })),
|
|
109
|
-
|
|
115
|
+
React.createElement(InfoIcon, { className: "pf-v5-u-ml-sm hostnameInfoIcon" })),
|
|
116
|
+
isFetchingUpdateHostnameDefault && (React.createElement(Spinner, { size: "lg", className: "pf-v5-u-ml-sm hostnameSpinner", "aria-label": "Hostname loading" }))));
|
|
110
117
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
(doNotShowModal === 1 && doNotShowNotClicked)) {
|
|
120
|
-
return React.createElement(React.Fragment, null);
|
|
121
|
-
}
|
|
122
|
-
return (React.createElement(React.Fragment, null,
|
|
123
|
-
React.createElement(Modal, { variant: ModalVariant.medium, title: "Share hostnames with Red Hat?", isOpen: isModalOpen, onClose: onCloseModal, actions: [
|
|
124
|
-
React.createElement(Button, { "data-tracking-id": "close-hostname-modal", key: "close", variant: "primary", onClick: onCloseModal }, "Close"),
|
|
125
|
-
React.createElement("div", { className: "dontAskCheckbox" },
|
|
126
|
-
React.createElement(Checkbox, { isChecked: !!doNotShowModal, label: "Don't ask me again", id: "dont-ask-again", "data-tracking-id": "dont-ask-again-hostname-modal", onChange: onDoNotAskAgain })),
|
|
127
|
-
] },
|
|
128
|
-
React.createElement("div", null,
|
|
129
|
-
React.createElement(Trans, null, "Red Hat Support cannot currently access hostnames that have been entered on a case. You can share this information at any time to improve your support experience, or you can ignore this.")),
|
|
130
|
-
modalBody())));
|
|
118
|
+
return (React.createElement(Modal, { variant: ModalVariant.medium, title: "Share hostnames with Red Hat?", isOpen: isModalOpen, onClose: onCloseModal, actions: [
|
|
119
|
+
React.createElement(Button, { "data-tracking-id": "close-hostname-modal", key: "close", variant: "primary", onClick: onCloseModal, isDisabled: isFetchingUpdateHostnameDefault }, "Close"),
|
|
120
|
+
React.createElement("div", { className: "dontAskCheckbox" },
|
|
121
|
+
React.createElement(Checkbox, { isChecked: !!doNotShowModal, label: "Don't ask me again", id: "dont-ask-again", "data-tracking-id": "dont-ask-again-hostname-modal", onChange: onDoNotAskAgain })),
|
|
122
|
+
] },
|
|
123
|
+
React.createElement("div", null,
|
|
124
|
+
React.createElement(Trans, null, "Red Hat Support cannot currently access hostnames that have been entered on a case. You can share this information at any time to improve your support experience, or you can ignore this.")),
|
|
125
|
+
modalBody()));
|
|
131
126
|
};
|