@rh-support/components 2.5.1 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/Functional/CaseContactsSelectorExternal.d.ts +12 -7
- package/lib/esm/Functional/CaseContactsSelectorExternal.d.ts.map +1 -1
- package/lib/esm/Functional/CaseContactsSelectorExternal.js +67 -60
- package/lib/esm/OwnerTypeaheadDropdown/OwnerTypeaheadDropdown.d.ts +17 -0
- package/lib/esm/OwnerTypeaheadDropdown/OwnerTypeaheadDropdown.d.ts.map +1 -0
- package/lib/esm/OwnerTypeaheadDropdown/OwnerTypeaheadDropdown.js +98 -0
- package/lib/esm/OwnerTypeaheadDropdown/index.d.ts +2 -0
- package/lib/esm/OwnerTypeaheadDropdown/index.d.ts.map +1 -0
- package/lib/esm/OwnerTypeaheadDropdown/index.js +1 -0
- package/lib/esm/SingleSelectDropdown/SingleSelectDropdown.d.ts +27 -0
- package/lib/esm/SingleSelectDropdown/SingleSelectDropdown.d.ts.map +1 -0
- package/lib/esm/SingleSelectDropdown/SingleSelectDropdown.js +26 -0
- package/lib/esm/SingleSelectDropdown/index.d.ts +2 -0
- package/lib/esm/SingleSelectDropdown/index.d.ts.map +1 -0
- package/lib/esm/SingleSelectDropdown/index.js +1 -0
- package/lib/esm/TypeaheadDropdown/TypeaheadDropdown.d.ts +39 -0
- package/lib/esm/TypeaheadDropdown/TypeaheadDropdown.d.ts.map +1 -0
- package/lib/esm/TypeaheadDropdown/TypeaheadDropdown.js +218 -0
- package/lib/esm/TypeaheadDropdown/index.d.ts +2 -0
- package/lib/esm/TypeaheadDropdown/index.d.ts.map +1 -0
- package/lib/esm/TypeaheadDropdown/index.js +1 -0
- package/lib/esm/hooks/index.d.ts +2 -0
- package/lib/esm/hooks/index.d.ts.map +1 -1
- package/lib/esm/hooks/index.js +2 -0
- package/lib/esm/hooks/usePatternFlySingleSelectToggle.d.ts +16 -0
- package/lib/esm/hooks/usePatternFlySingleSelectToggle.d.ts.map +1 -0
- package/lib/esm/hooks/usePatternFlySingleSelectToggle.js +17 -0
- package/lib/esm/hooks/useProgressiveLoading.d.ts +10 -0
- package/lib/esm/hooks/useProgressiveLoading.d.ts.map +1 -0
- package/lib/esm/hooks/useProgressiveLoading.js +33 -0
- package/lib/esm/hooks/useSelectKeyboardNavigator.d.ts +9 -1
- package/lib/esm/hooks/useSelectKeyboardNavigator.d.ts.map +1 -1
- package/lib/esm/hooks/useSelectKeyboardNavigator.js +82 -3
- package/lib/esm/index.d.ts +2 -1
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +2 -1
- package/package.json +6 -8
- package/lib/esm/DropDownList/AsyncDropDownList.d.ts +0 -6
- package/lib/esm/DropDownList/AsyncDropDownList.d.ts.map +0 -1
- package/lib/esm/DropDownList/AsyncDropDownList.js +0 -6
- package/lib/esm/DropDownList/DropDownList.d.ts +0 -9
- package/lib/esm/DropDownList/DropDownList.d.ts.map +0 -1
- package/lib/esm/DropDownList/DropDownList.js +0 -116
- package/lib/esm/DropDownList/DropdownWrapper.d.ts +0 -16
- package/lib/esm/DropDownList/DropdownWrapper.d.ts.map +0 -1
- package/lib/esm/DropDownList/DropdownWrapper.js +0 -19
- package/lib/esm/DropDownList/MultiSelectDropdownList.d.ts +0 -4
- package/lib/esm/DropDownList/MultiSelectDropdownList.d.ts.map +0 -1
- package/lib/esm/DropDownList/MultiSelectDropdownList.js +0 -4
- package/lib/esm/DropDownList/Readme.md +0 -114
- package/lib/esm/DropDownList/SearchableList.d.ts +0 -14
- package/lib/esm/DropDownList/SearchableList.d.ts.map +0 -1
- package/lib/esm/DropDownList/SearchableList.js +0 -98
- package/lib/esm/DropDownList/SelectList.d.ts +0 -11
- package/lib/esm/DropDownList/SelectList.d.ts.map +0 -1
- package/lib/esm/DropDownList/SelectList.js +0 -35
- package/lib/esm/DropDownList/async.d.ts +0 -9
- package/lib/esm/DropDownList/async.d.ts.map +0 -1
- package/lib/esm/DropDownList/async.js +0 -111
- package/lib/esm/DropDownList/dropdownList.css +0 -59
- package/lib/esm/DropDownList/dropdownUtils.d.ts +0 -5
- package/lib/esm/DropDownList/dropdownUtils.d.ts.map +0 -1
- package/lib/esm/DropDownList/dropdownUtils.js +0 -23
- package/lib/esm/DropDownList/index.d.ts +0 -4
- package/lib/esm/DropDownList/index.d.ts.map +0 -1
- package/lib/esm/DropDownList/index.js +0 -3
- package/lib/esm/DropDownList/types.d.ts +0 -53
- package/lib/esm/DropDownList/types.d.ts.map +0 -1
- package/lib/esm/DropDownList/types.js +0 -1
- package/lib/esm/DropDownList/withMulti.d.ts +0 -5
- package/lib/esm/DropDownList/withMulti.d.ts.map +0 -1
- package/lib/esm/DropDownList/withMulti.js +0 -46
|
@@ -4,9 +4,9 @@ import { IContact } from '@cee-eng/hydrajs/@types/models/contact';
|
|
|
4
4
|
import { IDClassNameProps } from '@rh-support/types/shared';
|
|
5
5
|
import { UserAuth } from '@rh-support/user-permissions';
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { ITypeaheadDropdownGroupOrOption } from '../TypeaheadDropdown/TypeaheadDropdown';
|
|
8
8
|
export type INotificationContact = IContact | ICaseNotificationAddresses;
|
|
9
|
-
interface IProps
|
|
9
|
+
interface IProps extends IDClassNameProps {
|
|
10
10
|
selectedAccountNumber: string;
|
|
11
11
|
selected: (IContact | ICaseNotificationAddresses)[];
|
|
12
12
|
onChange: (selectedContacts: (IContact | ICaseNotificationAddresses)[]) => void;
|
|
@@ -16,16 +16,21 @@ interface IProps<T extends TypeaheadModel> extends IDClassNameProps, Omit<Typeah
|
|
|
16
16
|
clearButton?: boolean;
|
|
17
17
|
multiple?: boolean;
|
|
18
18
|
placeholder?: string;
|
|
19
|
-
minLength?: number;
|
|
20
19
|
isUpdating?: boolean;
|
|
21
20
|
renderToken?: (option: any, props: any, idx: any) => string | React.ReactNode;
|
|
22
21
|
isExportingPDF?: boolean;
|
|
23
|
-
newSelectionPrefix?: React.ReactNode;
|
|
24
22
|
customEmails?: IAccountNotificationAddresses[];
|
|
25
23
|
isDisabled?: boolean;
|
|
24
|
+
allowCustomEmailAdd?: boolean;
|
|
25
|
+
isInvalid?: boolean;
|
|
26
|
+
groupContactsAndEmails?: boolean;
|
|
27
|
+
onNew?: (query: string) => void;
|
|
28
|
+
canAddNew?: (options: ITypeaheadDropdownGroupOrOption[], query: string) => boolean;
|
|
29
|
+
getCreateNewText?: (query: string) => string;
|
|
26
30
|
}
|
|
27
|
-
declare const
|
|
31
|
+
export declare const CONTACTS_PAGE_SIZE = 10;
|
|
32
|
+
export declare const DEFAULT_CONTACTS_OFFSET: number;
|
|
28
33
|
declare const getHydraContactLabel: (user: INotificationContact) => string;
|
|
29
|
-
declare function CaseContactsSelectorExternal
|
|
30
|
-
export { CaseContactsSelectorExternal,
|
|
34
|
+
declare function CaseContactsSelectorExternal(props: IProps): React.JSX.Element;
|
|
35
|
+
export { CaseContactsSelectorExternal, getHydraContactLabel };
|
|
31
36
|
//# sourceMappingURL=CaseContactsSelectorExternal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseContactsSelectorExternal.d.ts","sourceRoot":"","sources":["../../../src/Functional/CaseContactsSelectorExternal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAClE,OAAO,EAAuB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseContactsSelectorExternal.d.ts","sourceRoot":"","sources":["../../../src/Functional/CaseContactsSelectorExternal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAClE,OAAO,EAAuB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAQxD,OAAO,KAA4D,MAAM,OAAO,CAAC;AAIjF,OAAO,EAAE,+BAA+B,EAAE,MAAM,wCAAwC,CAAC;AAEzF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,0BAA0B,CAAC;AACzE,UAAU,MAAO,SAAQ,gBAAgB;IACrC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,QAAQ,GAAG,0BAA0B,CAAC,EAAE,CAAC;IACpD,QAAQ,EAAE,CAAC,gBAAgB,EAAE,CAAC,QAAQ,GAAG,0BAA0B,CAAC,EAAE,KAAK,IAAI,CAAC;IAChF,kBAAkB,EAAE,QAAQ,CAAC;IAC7B,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,MAAM,KAAA,EAAE,KAAK,KAAA,EAAE,GAAG,KAAA,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAC/D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,+BAA+B,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACnF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAChD;AAED,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,uBAAuB,QAAyB,CAAC;AAU9D,QAAA,MAAM,oBAAoB,SAAU,oBAAoB,KAAG,MAa1D,CAAC;AAEF,iBAAS,4BAA4B,CAAC,KAAK,EAAE,MAAM,qBA0NlD;AAED,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -7,40 +7,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
-
var t = {};
|
|
12
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
-
t[p] = s[p];
|
|
14
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
-
t[p[i]] = s[p[i]];
|
|
18
|
-
}
|
|
19
|
-
return t;
|
|
20
|
-
};
|
|
21
10
|
import { accounts } from '@cee-eng/hydrajs';
|
|
22
|
-
import { getApiResourceObject, sortHydraContacts } from '@rh-support/utils';
|
|
11
|
+
import { getApiResourceObject, isEmailValid, sortHydraContacts } from '@rh-support/utils';
|
|
23
12
|
import differenceBy from 'lodash/differenceBy';
|
|
13
|
+
import filter from 'lodash/filter';
|
|
24
14
|
import isArray from 'lodash/isArray';
|
|
25
15
|
import isEmpty from 'lodash/isEmpty';
|
|
16
|
+
import map from 'lodash/map';
|
|
26
17
|
import sortBy from 'lodash/sortBy';
|
|
27
|
-
import React, { useEffect, useRef, useState } from 'react';
|
|
28
|
-
import { Highlighter, Menu, MenuItem, Typeahead } from 'react-bootstrap-typeahead';
|
|
29
|
-
import { Trans } from 'react-i18next';
|
|
18
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
30
19
|
import { usePrevious } from '../hooks/usePrevious';
|
|
31
|
-
|
|
20
|
+
import { OwnerTypeaheadDropdown } from '../OwnerTypeaheadDropdown';
|
|
21
|
+
export const CONTACTS_PAGE_SIZE = 10;
|
|
22
|
+
export const DEFAULT_CONTACTS_OFFSET = CONTACTS_PAGE_SIZE - 1;
|
|
32
23
|
const isCustomEmailAddress = (user) => {
|
|
33
24
|
return !!(user === null || user === void 0 ? void 0 : user.emailAddress);
|
|
34
25
|
};
|
|
35
26
|
const isContact = (user) => {
|
|
36
27
|
return !!(user === null || user === void 0 ? void 0 : user.ssoUsername) && !(user === null || user === void 0 ? void 0 : user.emailAddress);
|
|
37
28
|
};
|
|
38
|
-
const getKey = (option) => {
|
|
39
|
-
if (isCustomEmailAddress(option))
|
|
40
|
-
return option.emailAddress;
|
|
41
|
-
if (isContact(option))
|
|
42
|
-
return option.ssoUsername;
|
|
43
|
-
};
|
|
44
29
|
const getHydraContactLabel = (user) => {
|
|
45
30
|
if (isEmpty(user) || typeof user !== 'object')
|
|
46
31
|
return '';
|
|
@@ -57,7 +42,9 @@ const getHydraContactLabel = (user) => {
|
|
|
57
42
|
return label ? label : '';
|
|
58
43
|
};
|
|
59
44
|
function CaseContactsSelectorExternal(props) {
|
|
45
|
+
const { customEmails, isInvalid, groupContactsAndEmails } = props;
|
|
60
46
|
const previousSelectedAccountNumber = usePrevious(props.selectedAccountNumber);
|
|
47
|
+
const [filteredContacts, setFilteredContacts] = useState([]);
|
|
61
48
|
/**
|
|
62
49
|
* External owner selector related
|
|
63
50
|
*/
|
|
@@ -147,7 +134,7 @@ function CaseContactsSelectorExternal(props) {
|
|
|
147
134
|
];
|
|
148
135
|
props.onChange && props.onChange(customerContacts);
|
|
149
136
|
};
|
|
150
|
-
const onCustomerContactSelectBlur = (
|
|
137
|
+
const onCustomerContactSelectBlur = () => {
|
|
151
138
|
props.onChange && props.onChange(props.selected);
|
|
152
139
|
};
|
|
153
140
|
const isDisabled = (props.loggedInUserRights.isExternal() &&
|
|
@@ -155,43 +142,63 @@ function CaseContactsSelectorExternal(props) {
|
|
|
155
142
|
props.isUpdating ||
|
|
156
143
|
contactList.isFetching ||
|
|
157
144
|
props.isDisabled;
|
|
158
|
-
const
|
|
159
|
-
const contacts = results.map((item, index) => {
|
|
160
|
-
if (item.customOption) {
|
|
161
|
-
return (React.createElement(MenuItem, { className: "rbt-menu-custom-option", key: index, option: item, position: index },
|
|
162
|
-
menuProps.newSelectionPrefix,
|
|
163
|
-
React.createElement(Highlighter, { search: state.text }, item['ssoUsername'])));
|
|
164
|
-
}
|
|
165
|
-
if (item.paginationOption) {
|
|
166
|
-
return (React.createElement(React.Fragment, { key: "pagination-item" },
|
|
167
|
-
React.createElement(Menu.Divider, null),
|
|
168
|
-
React.createElement(MenuItem, { key: index, position: index, option: item, className: "rbt-menu-pagination-option", label: "Display additional results..." }, "Display additional results...")));
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
return (React.createElement(React.Fragment, { key: index },
|
|
172
|
-
index === 0 && isContact(item) && (React.createElement(React.Fragment, null,
|
|
173
|
-
React.createElement(Menu.Header, null,
|
|
174
|
-
React.createElement(Trans, null, "Contacts")))),
|
|
175
|
-
(index === 0
|
|
176
|
-
? isCustomEmailAddress(item)
|
|
177
|
-
: isCustomEmailAddress(item) && isContact(results[index - 1])) && (React.createElement(React.Fragment, null,
|
|
178
|
-
index !== 0 && React.createElement(Menu.Divider, null),
|
|
179
|
-
React.createElement(Menu.Header, null,
|
|
180
|
-
React.createElement(Trans, null, "Notification emails")))),
|
|
181
|
-
React.createElement(MenuItem, { key: index, option: item, position: index }, renderMenuItemChildren(item, state))));
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
return React.createElement(Menu, Object.assign({}, menuProps), contacts);
|
|
185
|
-
};
|
|
186
|
-
const { customEmails } = props, restProps = __rest(props, ["customEmails"]);
|
|
187
|
-
const conditionalProps = Object.assign(Object.assign({}, (props.renderToken ? { renderToken: props.renderToken } : undefined)), ((customEmails || []).length > 0 ? { renderMenu } : undefined));
|
|
188
|
-
const getCustomEmails = () => {
|
|
145
|
+
const getCustomEmails = useCallback(() => {
|
|
189
146
|
return sortBy((customEmails || []).map((item) => (Object.assign(Object.assign({}, item), { ssoUsername: item.emailAddress, firstName: item.emailAddress, lastName: item.emailAddress }))), 'emailAddress');
|
|
147
|
+
}, [customEmails]);
|
|
148
|
+
/**
|
|
149
|
+
* Get all options for the owner typeahead.
|
|
150
|
+
*/
|
|
151
|
+
const allOptions = useMemo(() => {
|
|
152
|
+
return [
|
|
153
|
+
...map(contactList.data, (contact) => ({ contact, isCustomEmail: false })),
|
|
154
|
+
...map(getCustomEmails(), (email) => ({
|
|
155
|
+
isCustomEmail: true,
|
|
156
|
+
contact: Object.assign(Object.assign({}, email), { ssoUsername: email.emailAddress, firstName: email.emailAddress, lastName: email.emailAddress }),
|
|
157
|
+
})),
|
|
158
|
+
];
|
|
159
|
+
}, [contactList.data, getCustomEmails]);
|
|
160
|
+
/**
|
|
161
|
+
* update the shown options in the dropdown and reset the amount of options show to the default.
|
|
162
|
+
* @param query The user search term
|
|
163
|
+
*/
|
|
164
|
+
const onQueryUpdated = (query) => {
|
|
165
|
+
if (isEmpty(query)) {
|
|
166
|
+
setFilteredContacts(allOptions);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const filteredContacts = filter(allOptions, (option) => getHydraContactLabel(option.contact).toLowerCase().includes(query.toLowerCase()));
|
|
170
|
+
setFilteredContacts(filteredContacts);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Reset the filtered contacts and the current offset.
|
|
175
|
+
*/
|
|
176
|
+
const onClearQuery = () => {
|
|
177
|
+
var _a;
|
|
178
|
+
const numOfCustomEmails = (_a = customEmails === null || customEmails === void 0 ? void 0 : customEmails.length) !== null && _a !== void 0 ? _a : 0;
|
|
179
|
+
if (filteredContacts.length === contactList.data.length + numOfCustomEmails)
|
|
180
|
+
return;
|
|
181
|
+
setFilteredContacts(allOptions);
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Removes contacts based on the hydra
|
|
185
|
+
*/
|
|
186
|
+
const onChipRemoved = (option) => {
|
|
187
|
+
props.onChange(filter(props.selected, (c) => c !== option));
|
|
188
|
+
};
|
|
189
|
+
const canAddNew = (options, query) => {
|
|
190
|
+
if (!props.allowCustomEmailAdd)
|
|
191
|
+
return false;
|
|
192
|
+
if ((options || []).length === 0 && isEmailValid(query))
|
|
193
|
+
return true;
|
|
194
|
+
return false;
|
|
190
195
|
};
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
+
/**
|
|
197
|
+
* Set the filtered contacts to the entire contact list and reset the offset to the default page size.
|
|
198
|
+
*/
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
setFilteredContacts(allOptions);
|
|
201
|
+
}, [contactList.data, customEmails, allOptions]);
|
|
202
|
+
return (React.createElement(OwnerTypeaheadDropdown, { id: props.id || '', hasClearButton: true, multiple: !!props.multiple, groupContactsAndEmails: groupContactsAndEmails, selected: !isEmpty(props.selected) ? props.selected : [], options: filteredContacts, placeholder: props.placeholder || 'Search by name or username', "data-tracking-id": "external-case-contact-selector", isDisabled: isDisabled, status: isInvalid ? 'danger' : undefined, onChipRemoved: onChipRemoved, onClearQuery: onClearQuery, onQueryUpdated: onQueryUpdated, onBlur: onCustomerContactSelectBlur, onSelect: onCustomerContactSelect, canAddNew: canAddNew, getCreateNewText: props === null || props === void 0 ? void 0 : props.getCreateNewText }));
|
|
196
203
|
}
|
|
197
|
-
export { CaseContactsSelectorExternal,
|
|
204
|
+
export { CaseContactsSelectorExternal, getHydraContactLabel };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IContact } from '@cee-eng/hydrajs/@types/models/contact';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ITypeaheadDropdownProps } from '../TypeaheadDropdown/TypeaheadDropdown';
|
|
4
|
+
export type IOwnerSelectorExtends = Omit<ITypeaheadDropdownProps, 'selected' | 'options' | 'onSelect' | 'onHandleLoadMore' | 'isShowMoreOptionVisible' | 'onChipRemoved' | 'onNew'>;
|
|
5
|
+
export interface IOwnerSelectorProps extends IOwnerSelectorExtends {
|
|
6
|
+
selected: IContact[];
|
|
7
|
+
options: IOwnerOption[];
|
|
8
|
+
groupContactsAndEmails?: boolean;
|
|
9
|
+
onSelect: (contacts: IContact[]) => void;
|
|
10
|
+
onChipRemoved?: (contact: IContact) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface IOwnerOption {
|
|
13
|
+
contact: IContact;
|
|
14
|
+
isCustomEmail?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function OwnerTypeaheadDropdown(props: IOwnerSelectorProps): React.JSX.Element;
|
|
17
|
+
//# sourceMappingURL=OwnerTypeaheadDropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OwnerTypeaheadDropdown.d.ts","sourceRoot":"","sources":["../../../src/OwnerTypeaheadDropdown/OwnerTypeaheadDropdown.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAKlE,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,OAAO,EAGH,uBAAuB,EAE1B,MAAM,wCAAwC,CAAC;AAGhD,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACpC,uBAAuB,EACvB,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,kBAAkB,GAAG,yBAAyB,GAAG,eAAe,GAAG,OAAO,CACnH,CAAC;AAEF,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB;IAC9D,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,QAAQ,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,qBA6GhE"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import filter from 'lodash/filter';
|
|
13
|
+
import find from 'lodash/find';
|
|
14
|
+
import isEmpty from 'lodash/isEmpty';
|
|
15
|
+
import map from 'lodash/map';
|
|
16
|
+
import React, { useMemo } from 'react';
|
|
17
|
+
import { useTranslation } from 'react-i18next';
|
|
18
|
+
import { getHydraContactLabel } from '../Functional/CaseContactsSelectorExternal';
|
|
19
|
+
import { useProgressiveLoading } from '../hooks/useProgressiveLoading';
|
|
20
|
+
import { TypeaheadDropdown, } from '../TypeaheadDropdown/TypeaheadDropdown';
|
|
21
|
+
const PAGE_SIZE = 10;
|
|
22
|
+
function getTypeaheadOptionsFromContacts(contacts) {
|
|
23
|
+
return map(contacts, (o) => ({ label: getHydraContactLabel(o), value: o.ssoUsername }));
|
|
24
|
+
}
|
|
25
|
+
export function OwnerTypeaheadDropdown(props) {
|
|
26
|
+
const { groupContactsAndEmails, options, selected, onSelect, onBlur, onToggleClosed, onChipRemoved } = props, restProps = __rest(props, ["groupContactsAndEmails", "options", "selected", "onSelect", "onBlur", "onToggleClosed", "onChipRemoved"]);
|
|
27
|
+
const selectedTypeaheadOptions = useMemo(() => getTypeaheadOptionsFromContacts(selected), [selected]);
|
|
28
|
+
const { t } = useTranslation();
|
|
29
|
+
const { visibleItems, hasMoreItems, onHandleLoadMore, resetVisibleItems } = useProgressiveLoading(options, PAGE_SIZE);
|
|
30
|
+
const typeaheadOptions = useMemo(() => {
|
|
31
|
+
const contacts = [];
|
|
32
|
+
const customEmails = [];
|
|
33
|
+
for (const option of visibleItems) {
|
|
34
|
+
const typeaheadOption = { label: getHydraContactLabel(option.contact), value: option.contact.ssoUsername };
|
|
35
|
+
if (option.isCustomEmail) {
|
|
36
|
+
customEmails.push(typeaheadOption);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
contacts.push(typeaheadOption);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const allOptions = [];
|
|
43
|
+
const isContactsEmpty = isEmpty(contacts);
|
|
44
|
+
const isCustomEmailsEmpty = isEmpty(customEmails);
|
|
45
|
+
// If there are only contacts do not group the options together.
|
|
46
|
+
if (!groupContactsAndEmails) {
|
|
47
|
+
allOptions.push(...contacts);
|
|
48
|
+
allOptions.push(...customEmails);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (!isContactsEmpty) {
|
|
52
|
+
allOptions.push({ groupLabel: t('Contacts'), options: contacts });
|
|
53
|
+
}
|
|
54
|
+
if (!isCustomEmailsEmpty) {
|
|
55
|
+
allOptions.push({ groupLabel: t('Notification emails'), options: customEmails });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return allOptions;
|
|
59
|
+
// This only needs to run when the visible items change.
|
|
60
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
61
|
+
}, [visibleItems]);
|
|
62
|
+
/**
|
|
63
|
+
* Handles selecting or deselecting a contact.
|
|
64
|
+
*
|
|
65
|
+
* @param {React.MouseEvent<Element, MouseEvent>} _
|
|
66
|
+
* @param contactLabel The value of the selected option.
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
const onSelectContact = (selectedOptions) => {
|
|
70
|
+
const selectedContacts = map(filter(options, (option) => !!find(selectedOptions, (selectedOption) => selectedOption.value === option.contact.ssoUsername)), (o) => o.contact);
|
|
71
|
+
onSelect(selectedContacts);
|
|
72
|
+
};
|
|
73
|
+
const onLocalBlur = (event) => {
|
|
74
|
+
resetVisibleItems();
|
|
75
|
+
!!onBlur && onBlur(event);
|
|
76
|
+
};
|
|
77
|
+
const onLocalToggleClosed = () => {
|
|
78
|
+
resetVisibleItems();
|
|
79
|
+
!!onToggleClosed && onToggleClosed();
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Finds the correct contact that will be removed.
|
|
83
|
+
* @param option The option that is to be removed.
|
|
84
|
+
*/
|
|
85
|
+
const onLocalChipRemoved = (option) => {
|
|
86
|
+
const contact = find(selected, (o) => o.ssoUsername === option.value);
|
|
87
|
+
if (contact && !!onChipRemoved) {
|
|
88
|
+
onChipRemoved(contact);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const onLocalNew = (query) => {
|
|
92
|
+
const newCustomOption = {
|
|
93
|
+
emailAddress: query,
|
|
94
|
+
};
|
|
95
|
+
onSelect([newCustomOption]);
|
|
96
|
+
};
|
|
97
|
+
return (React.createElement(TypeaheadDropdown, Object.assign({ "data-tracking-id": "external-case-contact-selector", selected: selectedTypeaheadOptions, options: typeaheadOptions, onSelect: onSelectContact, onHandleLoadMore: onHandleLoadMore, isShowMoreOptionVisible: hasMoreItems(), onBlur: onLocalBlur, onToggleClosed: onLocalToggleClosed, onChipRemoved: onLocalChipRemoved, onNew: onLocalNew }, restProps)));
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/OwnerTypeaheadDropdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './OwnerTypeaheadDropdown';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ISingleSelectDropdownOption {
|
|
3
|
+
value: any;
|
|
4
|
+
label: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface SingleSelectDropdownProps {
|
|
9
|
+
selected: ISingleSelectDropdownOption;
|
|
10
|
+
options: ISingleSelectDropdownOption[];
|
|
11
|
+
isDisabled?: boolean;
|
|
12
|
+
isLoading?: boolean;
|
|
13
|
+
id?: string;
|
|
14
|
+
ariaLabel?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
isInvalid?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
toggleClassName?: string;
|
|
19
|
+
dataTrackingId?: string;
|
|
20
|
+
toggleDataTrackingId?: string;
|
|
21
|
+
onSelect?: (options: ISingleSelectDropdownOption[]) => void;
|
|
22
|
+
onBlur?: (event: React.FocusEvent<HTMLDivElement>) => void;
|
|
23
|
+
isScrollable?: boolean;
|
|
24
|
+
zIndex?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function SingleSelectDropdown(props: SingleSelectDropdownProps): React.JSX.Element;
|
|
27
|
+
//# sourceMappingURL=SingleSelectDropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SingleSelectDropdown.d.ts","sourceRoot":"","sources":["../../../src/SingleSelectDropdown/SingleSelectDropdown.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAE7C,MAAM,WAAW,2BAA2B;IACxC,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,yBAAyB;IACtC,QAAQ,EAAE,2BAA2B,CAAC;IACtC,OAAO,EAAE,2BAA2B,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,EAAE,KAAK,IAAI,CAAC;IAC5D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC3D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,qBAyFpE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Flex, FlexItem, MenuToggle, Select, SelectList, SelectOption, Spinner, } from '@patternfly/react-core';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
export function SingleSelectDropdown(props) {
|
|
5
|
+
const { selected, options, isDisabled, isLoading, id, placeholder, isInvalid, className, toggleClassName, dataTrackingId, toggleDataTrackingId, onSelect, isScrollable, onBlur, ariaLabel, zIndex, } = props;
|
|
6
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
7
|
+
const onToggleClick = () => {
|
|
8
|
+
setIsOpen(!isOpen);
|
|
9
|
+
};
|
|
10
|
+
const toggle = (toggleRef) => (React.createElement(MenuToggle, { className: toggleClassName || 'single-select-toggle-text', ref: toggleRef, onClick: onToggleClick, isExpanded: isOpen, isDisabled: isDisabled, isFullWidth: true, status: isInvalid ? 'danger' : undefined, "data-tracking-id": toggleDataTrackingId || '' },
|
|
11
|
+
React.createElement(Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
|
|
12
|
+
React.createElement(FlexItem, null,
|
|
13
|
+
" ",
|
|
14
|
+
selected.label || placeholder),
|
|
15
|
+
isLoading && (React.createElement(FlexItem, null,
|
|
16
|
+
React.createElement(Spinner, { size: "md" }))))));
|
|
17
|
+
const onLocalSelect = (event, value) => {
|
|
18
|
+
onSelect && onSelect(value);
|
|
19
|
+
setIsOpen(false);
|
|
20
|
+
};
|
|
21
|
+
const onLocalBlur = (event, value) => {
|
|
22
|
+
!!onBlur && onBlur(value);
|
|
23
|
+
};
|
|
24
|
+
return (React.createElement(Select, { id: id || '', className: className || '', "data-tracking-id": dataTrackingId, isOpen: isOpen, selected: selected, onSelect: onLocalSelect, onOpenChange: (isOpen) => setIsOpen(isOpen), toggle: toggle, shouldFocusToggleOnSelect: true, popperProps: { direction: 'down', enableFlip: false }, isScrollable: isScrollable, shouldFocusFirstItemOnOpen: false, onBlur: () => onLocalBlur, "aria-label": ariaLabel, zIndex: zIndex },
|
|
25
|
+
React.createElement(SelectList, null, options.map((option) => (React.createElement(SelectOption, { key: option.value, value: option, description: option.description || '', isSelected: isEqual(selected.label, option.label), isDisabled: option.disabled }, option.label))))));
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/SingleSelectDropdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SingleSelectDropdown';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ITypeaheadDropdownProps {
|
|
3
|
+
selected: ITypeaheadDropdownOption[];
|
|
4
|
+
options: ITypeaheadDropdownGroupOrOption[];
|
|
5
|
+
isShowMoreOptionVisible?: boolean;
|
|
6
|
+
id?: string;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
inputAriaControls?: string;
|
|
9
|
+
isDisabled?: boolean;
|
|
10
|
+
multiple?: boolean;
|
|
11
|
+
hasClearButton?: boolean;
|
|
12
|
+
defaultIsOpen?: boolean;
|
|
13
|
+
status?: 'success' | 'warning' | 'danger' | undefined;
|
|
14
|
+
onSelect: (options: ITypeaheadDropdownOption[]) => void;
|
|
15
|
+
onBlur?: (event: React.FocusEvent<HTMLDivElement>) => void;
|
|
16
|
+
onToggleClosed?: () => void;
|
|
17
|
+
onClearQuery?: () => void;
|
|
18
|
+
onChipRemoved?: (option: ITypeaheadDropdownOption) => void;
|
|
19
|
+
onQueryUpdated?: (query: string) => void;
|
|
20
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
21
|
+
onHandleLoadMore?: (event: any) => void;
|
|
22
|
+
onNew?: (query: string) => void;
|
|
23
|
+
canAddNew?: (options: ITypeaheadDropdownGroupOrOption[], query: string) => boolean;
|
|
24
|
+
getCreateNewText?: (query: string) => string;
|
|
25
|
+
}
|
|
26
|
+
export interface ITypeaheadDropdownOption {
|
|
27
|
+
value: any;
|
|
28
|
+
label: string;
|
|
29
|
+
group?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ITypeaheadDropdownGroup {
|
|
32
|
+
groupLabel: string;
|
|
33
|
+
options: ITypeaheadDropdownOption[];
|
|
34
|
+
}
|
|
35
|
+
export type ITypeaheadDropdownGroupOrOption = ITypeaheadDropdownOption | ITypeaheadDropdownGroup;
|
|
36
|
+
export declare const VIEW_MORE_OPTION_VALUE = "view-more-option-value";
|
|
37
|
+
export declare const ADD_NEW_OPTION_VALUE = "new-option-value";
|
|
38
|
+
export declare function TypeaheadDropdown(props: ITypeaheadDropdownProps): React.JSX.Element;
|
|
39
|
+
//# sourceMappingURL=TypeaheadDropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypeaheadDropdown.d.ts","sourceRoot":"","sources":["../../../src/TypeaheadDropdown/TypeaheadDropdown.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAMnD,MAAM,WAAW,uBAAuB;IACpC,QAAQ,EAAE,wBAAwB,EAAE,CAAC;IACrC,OAAO,EAAE,+BAA+B,EAAE,CAAC;IAC3C,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAEtD,QAAQ,EAAE,CAAC,OAAO,EAAE,wBAAwB,EAAE,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC3D,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC3D,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IACxC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,+BAA+B,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACnF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAChD;AAED,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACvC;AAED,MAAM,MAAM,+BAA+B,GAAG,wBAAwB,GAAG,uBAAuB,CAAC;AACjG,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AA2BvD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,uBAAuB,qBAqT/D"}
|