@rh-support/components 2.5.6 → 2.5.9

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.
@@ -11,6 +11,7 @@ interface IProps extends IDClassNameProps {
11
11
  selected: (IContact | ICaseNotificationAddresses)[];
12
12
  onChange: (selectedContacts: (IContact | ICaseNotificationAddresses)[]) => void;
13
13
  loggedInUserRights: UserAuth;
14
+ contactSsoUsername: string;
14
15
  contactsToExclude?: IContact[];
15
16
  name?: string;
16
17
  clearButton?: boolean;
@@ -30,6 +31,7 @@ interface IProps extends IDClassNameProps {
30
31
  }
31
32
  export declare const CONTACTS_PAGE_SIZE = 10;
32
33
  export declare const DEFAULT_CONTACTS_OFFSET: number;
34
+ export declare const isCustomEmailAddress: (user: INotificationContact) => user is ICaseNotificationAddresses;
33
35
  declare const getHydraContactLabel: (user: INotificationContact) => string;
34
36
  declare function CaseContactsSelectorExternal(props: IProps): React.JSX.Element;
35
37
  export { CaseContactsSelectorExternal, getHydraContactLabel };
@@ -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;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,qBA2NlD;AAED,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,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,kBAAkB,EAAE,MAAM,CAAC;IAC3B,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;AAE9D,eAAO,MAAM,oBAAoB,SAAU,oBAAoB,KAAG,IAAI,IAAI,0BAEzE,CAAC;AAMF,QAAA,MAAM,oBAAoB,SAAU,oBAAoB,KAAG,MAa1D,CAAC;AAEF,iBAAS,4BAA4B,CAAC,KAAK,EAAE,MAAM,qBA4NlD;AAED,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,CAAC"}
@@ -20,7 +20,7 @@ import { usePrevious } from '../hooks/usePrevious';
20
20
  import { OwnerTypeaheadDropdown } from '../OwnerTypeaheadDropdown';
21
21
  export const CONTACTS_PAGE_SIZE = 10;
22
22
  export const DEFAULT_CONTACTS_OFFSET = CONTACTS_PAGE_SIZE - 1;
23
- const isCustomEmailAddress = (user) => {
23
+ export const isCustomEmailAddress = (user) => {
24
24
  return !!(user === null || user === void 0 ? void 0 : user.emailAddress);
25
25
  };
26
26
  const isContact = (user) => {
@@ -42,7 +42,7 @@ const getHydraContactLabel = (user) => {
42
42
  return label ? label : '';
43
43
  };
44
44
  function CaseContactsSelectorExternal(props) {
45
- const { customEmails, isInvalid, groupContactsAndEmails } = props;
45
+ const { customEmails, contactSsoUsername, isInvalid, groupContactsAndEmails, selected } = props;
46
46
  const previousSelectedAccountNumber = usePrevious(props.selectedAccountNumber);
47
47
  const [filteredContacts, setFilteredContacts] = useState([]);
48
48
  /**
@@ -184,7 +184,7 @@ function CaseContactsSelectorExternal(props) {
184
184
  * Removes contacts based on the hydra
185
185
  */
186
186
  const onChipRemoved = (option) => {
187
- props.onChange(filter(props.selected, (c) => c !== option));
187
+ props.onChange([option]);
188
188
  };
189
189
  const canAddNew = (options, query) => {
190
190
  if (!props.allowCustomEmailAdd)
@@ -198,7 +198,7 @@ function CaseContactsSelectorExternal(props) {
198
198
  */
199
199
  useEffect(() => {
200
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, isLoading: props.isUpdating || contactList.isFetching }));
201
+ }, [contactList.data, customEmails, allOptions, selected]);
202
+ return (React.createElement(OwnerTypeaheadDropdown, { id: props.id || '', hasClearButton: true, multiple: !!props.multiple, contactSsoUsername: contactSsoUsername, 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, isLoading: props.isUpdating || contactList.isFetching }));
203
203
  }
204
204
  export { CaseContactsSelectorExternal, getHydraContactLabel };
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownEditor.d.ts","sourceRoot":"","sources":["../../../src/MarkdownEditor/MarkdownEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAwB,MAAM,qBAAqB,CAAC;AAgC7E,OAAO,KAAK,EAAE,EAAE,SAAS,EAA+B,MAAM,OAAO,CAAC;AAMtE,oBAAY,UAAU;IAClB,KAAK,cAAc;IACnB,QAAQ,aAAa;CACxB;AAED,UAAU,kBAAkB;IACxB,yBAAyB,EAAE,OAAO,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;IAClC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,IAAI,KAAA,KAAK,IAAI,CAAC;IACjC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,eAAe,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtG,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACnD;AA0BD,eAAO,MAAM,YAAY,SAAU,OAAO,CAAC,WAAW,CAAC,KAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAc7F,CAAC;AAEF,iBAAS,cAAc,CAAC,KAAK,EAAE,cAAc,qBAi8B5C;kBAj8BQ,cAAc;;;AAq8BvB,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"MarkdownEditor.d.ts","sourceRoot":"","sources":["../../../src/MarkdownEditor/MarkdownEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAwB,MAAM,qBAAqB,CAAC;AA+B7E,OAAO,KAAK,EAAE,EAAE,SAAS,EAA+B,MAAM,OAAO,CAAC;AAMtE,oBAAY,UAAU;IAClB,KAAK,cAAc;IACnB,QAAQ,aAAa;CACxB;AAED,UAAU,kBAAkB;IACxB,yBAAyB,EAAE,OAAO,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;IAClC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,IAAI,KAAA,KAAK,IAAI,CAAC;IACjC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,eAAe,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtG,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACnD;AA2BD,eAAO,MAAM,YAAY,SAAU,OAAO,CAAC,WAAW,CAAC,KAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAiB7F,CAAC;AAEF,iBAAS,cAAc,CAAC,KAAK,EAAE,cAAc,qBA87B5C;kBA97BQ,cAAc;;;AAk8BvB,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -19,7 +19,6 @@ import ImageIcon from '@patternfly/react-icons/dist/js/icons/image-icon';
19
19
  import LinkIcon from '@patternfly/react-icons/dist/js/icons/link-icon';
20
20
  import ListUlIcon from '@patternfly/react-icons/dist/js/icons/list-ul-icon';
21
21
  import QuoteRightIcon from '@patternfly/react-icons/dist/js/icons/quote-right-icon';
22
- import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon';
23
22
  import { emojiPattern, haltEvent, isEmojiPattern, isImageFile } from '@rh-support/utils';
24
23
  import cx from 'classnames';
25
24
  import DOMPurify from 'dompurify';
@@ -59,18 +58,21 @@ export const validateFile = (file) => {
59
58
  // Check file type
60
59
  if (!ALLOWED_FILE_TYPES.includes(file.fileType)) {
61
60
  // ToastNotification.addDangerMessage(t('Invalid file type, Only JPEG, PNG, GIF files are allowed.'));
62
- return { isValid: false, errorMsg: 'Invalid file type, Only JPEG, PNG, GIF files are allowed.' };
61
+ return {
62
+ isValid: false,
63
+ errorMsg: 'Invalid file type, Only JPEG, PNG, GIF files are allowed inside Markdown Editor',
64
+ };
63
65
  }
64
66
  // Check file size
65
67
  if (file.sizeKB > MAX_FILE_SIZE) {
66
68
  // ToastNotification.addDangerMessage(t('File too large, File size must be less than 2MB'));
67
- return { isValid: false, errorMsg: 'File too large, File size must be less than 2MB' };
69
+ return { isValid: false, errorMsg: 'File too large, File size must be less than 2MB inside Markdown Editor' };
68
70
  }
69
71
  return { isValid: true, errorMsg: '' };
70
72
  };
71
73
  function MarkdownEditor(props) {
72
74
  const { t } = useTranslation();
73
- const { hidePreviewText, showPreviewText, mdPlaceholder, plainTextPlaceholder, textAreaClassName, bindTextArea, markedownOptions, allowEmoji, hideHeadingOptions, rows, showMarkdownPlainTextToggle, editorMode, className, charLimit, minCharsForCounter, id, value, onCommentExceedCharsLimit, fileSelectorProps: { onClipboardPaste, onFileDelete, onFileSelect, isSupportedFile, showFileSelectorInToolbar = false, isUploadingFile = false, filesList = [], attachFileBtn, } } = props, textAreaProps = __rest(props, ["hidePreviewText", "showPreviewText", "mdPlaceholder", "plainTextPlaceholder", "textAreaClassName", "bindTextArea", "markedownOptions", "allowEmoji", "hideHeadingOptions", "rows", "showMarkdownPlainTextToggle", "editorMode", "className", "charLimit", "minCharsForCounter", "id", "value", "onCommentExceedCharsLimit", "fileSelectorProps"]);
75
+ const { hidePreviewText, showPreviewText, mdPlaceholder, plainTextPlaceholder, textAreaClassName, bindTextArea, markedownOptions, allowEmoji, hideHeadingOptions, rows, showMarkdownPlainTextToggle, editorMode, className, charLimit, minCharsForCounter, id, value, onCommentExceedCharsLimit, fileSelectorProps: { onClipboardPaste, onFileSelect, isSupportedFile, showFileSelectorInToolbar = false, isUploadingFile = false, filesList = [], attachFileBtn, } } = props, textAreaProps = __rest(props, ["hidePreviewText", "showPreviewText", "mdPlaceholder", "plainTextPlaceholder", "textAreaClassName", "bindTextArea", "markedownOptions", "allowEmoji", "hideHeadingOptions", "rows", "showMarkdownPlainTextToggle", "editorMode", "className", "charLimit", "minCharsForCounter", "id", "value", "onCommentExceedCharsLimit", "fileSelectorProps"]);
74
76
  const [isPreview, setIsPreview] = useState(false);
75
77
  const [mdValue, setMdValue] = useState(props.value || '');
76
78
  const previousFileList = usePrevious(filesList);
@@ -80,6 +82,7 @@ function MarkdownEditor(props) {
80
82
  // for access inside event handlers
81
83
  const isPlainModeEnabledRef = useRef(isPlainModeEnabled);
82
84
  const [isFileSelectorOpen, setIsFileSelectorOpen] = useState(false);
85
+ const [isFileFromOnPaste, setIsFileFromOnPaste] = useState(false);
83
86
  const onFileSelectLocal = () => {
84
87
  setIsFileSelectorOpen((open) => !open);
85
88
  };
@@ -87,11 +90,17 @@ function MarkdownEditor(props) {
87
90
  setIsFileSelectorOpen(isOpen);
88
91
  };
89
92
  useEffect(() => {
93
+ if (isFileFromOnPaste) {
94
+ onFileInsert(filesList[0]);
95
+ }
90
96
  if ((previousFileList || []).length < (filesList || []).length && isUploadingFile) {
91
97
  onFileInsert(filesList[0]);
92
98
  }
99
+ return () => {
100
+ setIsFileFromOnPaste(false);
101
+ };
93
102
  // eslint-disable-next-line react-hooks/exhaustive-deps
94
- }, [filesList]);
103
+ }, [filesList.length]);
95
104
  const onFileInsert = (file) => {
96
105
  const { isValid, errorMsg } = validateFile(file);
97
106
  if (!isValid) {
@@ -126,6 +135,7 @@ function MarkdownEditor(props) {
126
135
  const files = [file];
127
136
  event.preventDefault();
128
137
  onClipboardPaste(files);
138
+ setIsFileFromOnPaste(true);
129
139
  };
130
140
  // To handle dropped images
131
141
  const onDrop = (event) => {
@@ -137,23 +147,19 @@ function MarkdownEditor(props) {
137
147
  const files = [file];
138
148
  event.preventDefault();
139
149
  onClipboardPaste(files);
150
+ setIsFileFromOnPaste(true);
140
151
  };
141
152
  const getFileSelectorList = (isMobile = false) => {
142
- const filesAsDropdownItems = filesList.map((file) => {
153
+ const filesAsDropdownItems = filesList
154
+ .filter((file) => validateFile(file).isValid)
155
+ .map((file) => {
143
156
  return (React.createElement(React.Fragment, null,
144
157
  React.createElement(DropdownItem, { key: file.id, onClick: () => {
145
158
  onFileInsert(file);
146
159
  } },
147
160
  React.createElement(Flex, { flexWrap: { default: 'nowrap' } },
148
161
  React.createElement(FlexItem, null,
149
- React.createElement(Text, { component: TextVariants.small }, file.fileName)),
150
- onFileDelete && (React.createElement(FlexItem, { className: "pf-v5-u-ml-auto" },
151
- React.createElement(Button, { variant: ButtonVariant.plain, onClick: (event) => {
152
- onFileSelectToggle(false);
153
- onFileDelete(file);
154
- event.stopPropagation();
155
- } },
156
- React.createElement(TrashIcon, { color: "#c9190b" }))))))));
162
+ React.createElement(Text, { component: TextVariants.small }, file.fileName))))));
157
163
  });
158
164
  return isMobile
159
165
  ? [
@@ -5,6 +5,7 @@ export type IOwnerSelectorExtends = Omit<ITypeaheadDropdownProps, 'selected' | '
5
5
  export interface IOwnerSelectorProps extends IOwnerSelectorExtends {
6
6
  selected: IContact[];
7
7
  options: IOwnerOption[];
8
+ contactSsoUsername: string;
8
9
  groupContactsAndEmails?: boolean;
9
10
  onSelect: (contacts: IContact[]) => void;
10
11
  onChipRemoved?: (contact: IContact) => void;
@@ -1 +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;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,QAAQ,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,qBA6GhE"}
1
+ {"version":3,"file":"OwnerTypeaheadDropdown.d.ts","sourceRoot":"","sources":["../../../src/OwnerTypeaheadDropdown/OwnerTypeaheadDropdown.tsx"],"names":[],"mappings":"AAEA,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,kBAAkB,EAAE,MAAM,CAAC;IAC3B,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;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,QAAQ,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAcD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,qBA2HhE"}
@@ -15,23 +15,30 @@ import isEmpty from 'lodash/isEmpty';
15
15
  import map from 'lodash/map';
16
16
  import React, { useMemo } from 'react';
17
17
  import { useTranslation } from 'react-i18next';
18
- import { getHydraContactLabel } from '../Functional/CaseContactsSelectorExternal';
18
+ import { getHydraContactLabel, isCustomEmailAddress } from '../Functional/CaseContactsSelectorExternal';
19
19
  import { useProgressiveLoading } from '../hooks/useProgressiveLoading';
20
20
  import { TypeaheadDropdown, } from '../TypeaheadDropdown/TypeaheadDropdown';
21
21
  const PAGE_SIZE = 10;
22
- function getTypeaheadOptionsFromContacts(contacts) {
23
- return map(contacts, (o) => ({ label: getHydraContactLabel(o), value: o.ssoUsername }));
22
+ function getTypeaheadOptionsFromContacts(contacts, caseContactSsoUsername) {
23
+ return map(contacts, (o) => ({
24
+ label: getHydraContactLabel(o),
25
+ value: isCustomEmailAddress(o) ? o === null || o === void 0 ? void 0 : o.emailAddress : o === null || o === void 0 ? void 0 : o.ssoUsername,
26
+ disableDelete: o.ssoUsername === caseContactSsoUsername,
27
+ }));
24
28
  }
25
29
  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]);
30
+ const { contactSsoUsername, groupContactsAndEmails, options, selected, onSelect, onToggleClosed, onChipRemoved } = props, restProps = __rest(props, ["contactSsoUsername", "groupContactsAndEmails", "options", "selected", "onSelect", "onToggleClosed", "onChipRemoved"]);
31
+ const selectedTypeaheadOptions = useMemo(() => getTypeaheadOptionsFromContacts(selected, contactSsoUsername), [selected, contactSsoUsername]);
28
32
  const { t } = useTranslation();
29
33
  const { visibleItems, hasMoreItems, onHandleLoadMore, resetVisibleItems } = useProgressiveLoading(options, PAGE_SIZE);
30
34
  const typeaheadOptions = useMemo(() => {
31
35
  const contacts = [];
32
36
  const customEmails = [];
33
37
  for (const option of visibleItems) {
34
- const typeaheadOption = { label: getHydraContactLabel(option.contact), value: option.contact.ssoUsername };
38
+ const typeaheadOption = {
39
+ label: getHydraContactLabel(option.contact),
40
+ value: option.contact.ssoUsername,
41
+ };
35
42
  if (option.isCustomEmail) {
36
43
  customEmails.push(typeaheadOption);
37
44
  }
@@ -70,10 +77,6 @@ export function OwnerTypeaheadDropdown(props) {
70
77
  const selectedContacts = map(filter(options, (option) => !!find(selectedOptions, (selectedOption) => selectedOption.value === option.contact.ssoUsername)), (o) => o.contact);
71
78
  onSelect(selectedContacts);
72
79
  };
73
- const onLocalBlur = (event) => {
74
- resetVisibleItems();
75
- !!onBlur && onBlur(event);
76
- };
77
80
  const onLocalToggleClosed = () => {
78
81
  resetVisibleItems();
79
82
  !!onToggleClosed && onToggleClosed();
@@ -83,7 +86,7 @@ export function OwnerTypeaheadDropdown(props) {
83
86
  * @param option The option that is to be removed.
84
87
  */
85
88
  const onLocalChipRemoved = (option) => {
86
- const contact = find(selected, (o) => o.ssoUsername === option.value);
89
+ const contact = find(selected, (o) => (o === null || o === void 0 ? void 0 : o.ssoUsername) === option.value || (o === null || o === void 0 ? void 0 : o.emailAddress) === option.value);
87
90
  if (contact && !!onChipRemoved) {
88
91
  onChipRemoved(contact);
89
92
  }
@@ -94,5 +97,5 @@ export function OwnerTypeaheadDropdown(props) {
94
97
  };
95
98
  onSelect([newCustomOption]);
96
99
  };
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)));
100
+ return (React.createElement(TypeaheadDropdown, Object.assign({ "data-tracking-id": "external-case-contact-selector", selected: selectedTypeaheadOptions, options: typeaheadOptions, onSelect: onSelectContact, onHandleLoadMore: onHandleLoadMore, isShowMoreOptionVisible: hasMoreItems(), onToggleClosed: onLocalToggleClosed, onChipRemoved: onLocalChipRemoved, onNew: onLocalNew }, restProps)));
98
101
  }
@@ -587,7 +587,7 @@ export const FlagSvgs = () => {
587
587
  React.createElement("clipPath", { id: "clip0_301_1229" },
588
588
  React.createElement("rect", { width: "513", height: "341.967", fill: "white", transform: "translate(0 0.65918)" })))),
589
589
  React.createElement("symbol", { viewBox: "0 0 513 343", id: "cc_fr" },
590
- React.createElement("g", { "clip-path": "url(#clip0_301_1221)" },
590
+ React.createElement("g", { clipPath: "url(#clip0_301_1221)" },
591
591
  React.createElement("path", { d: "M0 0.925293H513V342.929H0V0.925293Z", fill: "white" }),
592
592
  React.createElement("path", { d: "M0 0.925293H170.996V342.929H0V0.925293Z", fill: "#0052B4" }),
593
593
  React.createElement("path", { d: "M342.004 0.925293H513V342.929H342.004V0.925293Z", fill: "#D80027" })),
@@ -1,3 +1,4 @@
1
+ import { LabelProps } from '@patternfly/react-core';
1
2
  import React from 'react';
2
3
  export interface ITypeaheadDropdownProps {
3
4
  selected: ITypeaheadDropdownOption[];
@@ -12,6 +13,7 @@ export interface ITypeaheadDropdownProps {
12
13
  defaultIsOpen?: boolean;
13
14
  status?: 'success' | 'warning' | 'danger' | undefined;
14
15
  isLoading?: boolean;
16
+ color?: LabelProps['color'];
15
17
  onSelect: (options: ITypeaheadDropdownOption[]) => void;
16
18
  onBlur?: (event: React.FocusEvent<HTMLDivElement>) => void;
17
19
  onToggleClosed?: () => void;
@@ -28,6 +30,7 @@ export interface ITypeaheadDropdownOption {
28
30
  value: any;
29
31
  label: string;
30
32
  group?: string;
33
+ disableDelete?: boolean;
31
34
  }
32
35
  export interface ITypeaheadDropdownGroup {
33
36
  groupLabel: string;
@@ -1 +1 @@
1
- {"version":3,"file":"TypeaheadDropdown.d.ts","sourceRoot":"","sources":["../../../src/TypeaheadDropdown/TypeaheadDropdown.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,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;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,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,qBAoT/D"}
1
+ {"version":3,"file":"TypeaheadDropdown.d.ts","sourceRoot":"","sources":["../../../src/TypeaheadDropdown/TypeaheadDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIH,UAAU,EAWb,MAAM,wBAAwB,CAAC;AAOhC,OAAO,KAAsC,MAAM,OAAO,CAAC;AAM3D,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;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAE5B,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;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;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,qBA8V/D"}
@@ -1,15 +1,13 @@
1
1
  import { Button, Label, LabelGroup, MenuToggle, Select, SelectGroup, SelectList, SelectOption, Spinner, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
2
2
  import TimesCircleIcon from '@patternfly/react-icons/dist/js/icons/times-circle-icon';
3
3
  import { haltEvent } from '@rh-support/utils';
4
- import concat from 'lodash/concat';
5
- import filter from 'lodash/filter';
6
4
  import find from 'lodash/find';
7
5
  import isEmpty from 'lodash/isEmpty';
8
- import isEqual from 'lodash/isEqual';
9
6
  import isNumber from 'lodash/isNumber';
10
7
  import isString from 'lodash/isString';
11
- import React, { useEffect, useState } from 'react';
8
+ import React, { useEffect, useRef, useState } from 'react';
12
9
  import { useTranslation } from 'react-i18next';
10
+ import { usePrevious } from '../hooks/usePrevious';
13
11
  import { useSelectKeyboardNavigator } from '../hooks/useSelectKeyboardNavigator';
14
12
  export const VIEW_MORE_OPTION_VALUE = 'view-more-option-value';
15
13
  export const ADD_NEW_OPTION_VALUE = 'new-option-value';
@@ -36,11 +34,13 @@ function flattenOptions(options) {
36
34
  }
37
35
  export function TypeaheadDropdown(props) {
38
36
  var _a;
39
- const { options, selected, hasClearButton, id, isDisabled, multiple, placeholder, isShowMoreOptionVisible, defaultIsOpen, inputAriaControls, status, onSelect, onBlur, onToggleClosed, onClearQuery, onChipRemoved, onQueryUpdated, onHandleLoadMore, onOpenChange, onNew, canAddNew, getCreateNewText, isLoading, } = props;
37
+ const { color, options, selected, hasClearButton, id, isDisabled, multiple, placeholder, isShowMoreOptionVisible, defaultIsOpen, inputAriaControls, status, onSelect, onBlur, onToggleClosed, onClearQuery, onChipRemoved, onQueryUpdated, onHandleLoadMore, onOpenChange, onNew, canAddNew, getCreateNewText, isLoading, } = props;
40
38
  const { t } = useTranslation();
41
39
  const [isOpen, setIsOpen] = useState(defaultIsOpen !== null && defaultIsOpen !== void 0 ? defaultIsOpen : false);
42
40
  const [query, setQuery] = useState(!multiple ? (!isEmpty(selected) ? selected[0].label : '') : '');
43
41
  const [allOptions, setAllOptions] = useState((_a = flattenOptions(options)) !== null && _a !== void 0 ? _a : []);
42
+ const prevSelected = usePrevious(selected);
43
+ const inputRef = useRef();
44
44
  const { focusedItemIndex, onInputKeyDown, setFocusedItemIndex } = useSelectKeyboardNavigator({
45
45
  ignoreResetOnListChange: true,
46
46
  isDisabled: isDisabled,
@@ -51,19 +51,38 @@ export function TypeaheadDropdown(props) {
51
51
  });
52
52
  /**
53
53
  * Allows the select toggle component to open and close itself.
54
+ * Resets the query for single select if the dropdown is going to be closed.
54
55
  */
55
56
  const handleToggle = () => {
56
57
  setIsOpen((open) => {
58
+ var _a, _b;
57
59
  const isOpen = !open;
60
+ if (!isEmpty(selected) && !multiple && !isOpen) {
61
+ setQuery((_b = (_a = selected[0]) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : '');
62
+ }
58
63
  return isOpen;
59
64
  });
60
65
  };
66
+ /**
67
+ * Opens the dropdown on click if it is not open.
68
+ */
69
+ const handleInputToggle = () => {
70
+ if (!isOpen) {
71
+ setIsOpen(true);
72
+ }
73
+ else if (isEmpty(query)) {
74
+ setIsOpen(false);
75
+ }
76
+ };
61
77
  /**
62
78
  * Set the query to an empty string when the clear button is pressed.
63
79
  */
64
80
  const handleClearQuery = (event) => {
81
+ var _a;
65
82
  setQuery('');
66
83
  onClearQuery && onClearQuery();
84
+ (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
85
+ setIsOpen(true);
67
86
  event === null || event === void 0 ? void 0 : event.stopPropagation();
68
87
  event === null || event === void 0 ? void 0 : event.preventDefault();
69
88
  };
@@ -75,17 +94,22 @@ export function TypeaheadDropdown(props) {
75
94
  const updateQuery = (event, v) => {
76
95
  setQuery(v);
77
96
  onQueryUpdated && onQueryUpdated(v);
97
+ setFocusedItemIndex(null);
78
98
  if (!isOpen) {
79
99
  setIsOpen(true);
80
100
  }
81
101
  };
82
102
  /**
83
103
  * Used by the Select patternfly component to change the toggle open state.
84
- * @param isOpen The state used to change the open state of the toggle
104
+ * @param newIsOpen The state used to change the open state of the toggle
85
105
  */
86
- const localOnOpenChange = (isOpen) => {
87
- setIsOpen(isOpen);
88
- !!onOpenChange && onOpenChange(isOpen);
106
+ const localOnOpenChange = (newIsOpen) => {
107
+ var _a, _b;
108
+ if (!isEmpty(selected) && !multiple && !newIsOpen) {
109
+ setQuery((_b = (_a = selected[0]) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : '');
110
+ }
111
+ setIsOpen(newIsOpen);
112
+ !!onOpenChange && onOpenChange(newIsOpen);
89
113
  };
90
114
  const isAlreadySelected = (option) => {
91
115
  return !!find(selected, (selectedOption) => selectedOption.value === option.value);
@@ -119,28 +143,28 @@ export function TypeaheadDropdown(props) {
119
143
  // Single selection: replace the selection with the new option
120
144
  onSelect([selectedOption]);
121
145
  setQuery(selectedOption.label);
146
+ !!onQueryUpdated && onQueryUpdated(selectedOption.label);
122
147
  }
123
148
  else {
124
- // Multiple selection: add or remove the contact
125
- const updatedSelection = isAlreadySelected(selectedOption)
126
- ? filter(selected, (o) => !isEqual(selectedOption, o)) // Remove
127
- : concat(selected, selectedOption); // Add
128
- onSelect(updatedSelection);
149
+ onSelect([selectedOption]);
129
150
  setQuery('');
151
+ !!onQueryUpdated && onQueryUpdated('');
130
152
  }
131
153
  setIsOpen(false);
132
154
  setFocusedItemIndex(null);
133
155
  };
134
- const toggle = (toggleRef) => (React.createElement(MenuToggle, { isFullWidth: true, variant: "typeahead", onClick: handleToggle, innerRef: toggleRef, isExpanded: isOpen, isDisabled: isDisabled, status: status },
135
- React.createElement(TextInputGroup, { isPlain: true },
136
- React.createElement(TextInputGroupMain, { value: query, placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : t(`Search by name or username`), onChange: updateQuery, onClick: handleToggle, onKeyDown: onInputKeyDown, isExpanded: isOpen, "aria-controls": inputAriaControls, role: "combobox" }, !!multiple && (React.createElement(LabelGroup, { "aria-label": "Current selections" }, selected.map((option, index) => (React.createElement(Label, { key: index, variant: "outline", onClick: haltEvent, onClose: (ev) => {
137
- haltEvent(ev);
138
- !!onChipRemoved && onChipRemoved(option);
139
- } }, option.label)))))),
140
- React.createElement(TextInputGroupUtilities, null,
141
- query && hasClearButton && !isDisabled && (React.createElement(Button, { "aria-label": "Clear input value", variant: "plain", onClick: handleClearQuery, isDisabled: isDisabled },
142
- React.createElement(TimesCircleIcon, null))),
143
- isLoading && React.createElement(Spinner, { size: "sm" })))));
156
+ const toggle = (toggleRef) => {
157
+ return (React.createElement(MenuToggle, { isFullWidth: true, variant: "typeahead", onClick: handleToggle, innerRef: toggleRef, isExpanded: isOpen, isDisabled: isDisabled, status: status },
158
+ React.createElement(TextInputGroup, { isPlain: true },
159
+ React.createElement(TextInputGroupMain, { value: query, placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : t(`Search by name or username`), innerRef: inputRef, onChange: updateQuery, onClick: handleInputToggle, onKeyDown: onInputKeyDown, isExpanded: isOpen, "aria-controls": inputAriaControls, role: "combobox" }, !!multiple && (React.createElement(LabelGroup, { "aria-label": "Current selections" }, selected.map((option, index) => (React.createElement(Label, { key: index, variant: "outline", onClick: haltEvent, color: color !== null && color !== void 0 ? color : 'blue', isDisabled: isDisabled || (option === null || option === void 0 ? void 0 : option.disableDelete), onClose: (ev) => {
160
+ haltEvent(ev);
161
+ !!onChipRemoved && onChipRemoved(option);
162
+ } }, option.label)))))),
163
+ React.createElement(TextInputGroupUtilities, null,
164
+ query && hasClearButton && !isDisabled && (React.createElement(Button, { "aria-label": "Clear input value", variant: "plain", onClick: handleClearQuery, isDisabled: isDisabled },
165
+ React.createElement(TimesCircleIcon, null))),
166
+ isLoading && React.createElement(Spinner, { size: "sm" })))));
167
+ };
144
168
  /**
145
169
  * Renders the options and group options.
146
170
  * @returns {JSX.Element[]} The rendered options.
@@ -190,7 +214,8 @@ export function TypeaheadDropdown(props) {
190
214
  else if (option.value === ADD_NEW_OPTION_VALUE) {
191
215
  return (React.createElement(SelectOption, { key: option.value, value: option.value, isFocused: false, isSelected: false }, !!getCreateNewText ? getCreateNewText(query) : `${option.label}: ${query}`));
192
216
  }
193
- return (React.createElement(SelectOption, { key: option.value, value: option.value, isFocused: focusedItemIndex === index, isSelected: isAlreadySelected(option) }, option.label));
217
+ const isSelected = isAlreadySelected(option);
218
+ return (React.createElement(SelectOption, { key: option.value, value: option.value, isFocused: focusedItemIndex === index, isSelected: isSelected, isDisabled: isSelected }, option.label));
194
219
  };
195
220
  useEffect(() => {
196
221
  const localAllOptions = [...flattenOptions(options)];
@@ -204,13 +229,22 @@ export function TypeaheadDropdown(props) {
204
229
  // There is no need to recall this when canAddNew has been changed.
205
230
  // eslint-disable-next-line react-hooks/exhaustive-deps
206
231
  }, [options, isShowMoreOptionVisible, query]);
232
+ /**
233
+ * Will set the query to the currently selected label if the previous selection
234
+ * was empty and the dropdown is single select.
235
+ */
236
+ useEffect(() => {
237
+ if (!multiple && isEmpty(prevSelected) && !isEmpty(selected)) {
238
+ setQuery(selected[0].label);
239
+ }
240
+ }, [selected, prevSelected, isOpen, multiple]);
207
241
  useEffect(() => {
208
242
  if (!isOpen) {
209
243
  setFocusedItemIndex(null);
210
244
  !!onToggleClosed && onToggleClosed();
211
245
  }
212
246
  // eslint-disable-next-line react-hooks/exhaustive-deps
213
- }, [isOpen]);
247
+ }, [isOpen, selected]);
214
248
  return (React.createElement(Select, { id: id || '', "data-tracking-id": "external-case-contact-selector", role: "menu", shouldFocusFirstItemOnOpen: false, shouldFocusToggleOnSelect: false, isOpen: isOpen, onOpenChange: localOnOpenChange, toggle: toggle, popperProps: { direction: 'down', enableFlip: false }, isScrollable: true, onBlur: onBlur, onSelect: onLocalSelect },
215
249
  React.createElement(SelectList, { isAriaMultiselectable: multiple }, ...renderOptions())));
216
250
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/components",
3
- "version": "2.5.6",
3
+ "version": "2.5.9",
4
4
  "description": "Contains all reusabel components for support app",
5
5
  "author": "Vikas Rathee <vrathee@redhat.com>",
6
6
  "license": "ISC",
@@ -106,5 +106,5 @@
106
106
  "defaults and supports es6-module",
107
107
  "maintained node versions"
108
108
  ],
109
- "gitHead": "b6a8eed6fd124d98a0da537fc889513e3e533f06"
109
+ "gitHead": "1eeedd5135ac6a9b24533268c5a260d164a3811e"
110
110
  }