@rh-support/cases 2.1.69 → 2.1.71

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.
@@ -1 +1 @@
1
- {"version":3,"file":"CaseList.d.ts","sourceRoot":"","sources":["../../../../src/components/case-list/CaseList.tsx"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAChC,OAAO,0BAA0B,CAAC;AA4BlC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAKH,0BAA0B,EAI7B,MAAM,mBAAmB,CAAC;AAK3B,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAe,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAK1C,OAAO,EAAgB,WAAW,EAA2B,MAAM,uBAAuB,CAAC;AAmC3F,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC3D,YAAY,EAAE,cAAc,EAAE,CAAC;CAClC;AAED,MAAM,MAAM,YAAY,GAAG,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAM5F,MAAM,WAAW,gBAAgB;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,qBA8frC"}
1
+ {"version":3,"file":"CaseList.d.ts","sourceRoot":"","sources":["../../../../src/components/case-list/CaseList.tsx"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAChC,OAAO,0BAA0B,CAAC;AA+BlC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAKH,0BAA0B,EAI7B,MAAM,mBAAmB,CAAC;AAK3B,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAe,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAK1C,OAAO,EAAgB,WAAW,EAA2B,MAAM,uBAAuB,CAAC;AAmC3F,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC3D,YAAY,EAAE,cAAc,EAAE,CAAC;CAClC;AAED,MAAM,MAAM,YAAY,GAAG,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAM5F,MAAM,WAAW,gBAAgB;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,qBAihBrC"}
@@ -15,7 +15,7 @@ import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/js/icons/angle-dou
15
15
  import AngleDoubleRightIcon from '@patternfly/react-icons/dist/js/icons/angle-double-right-icon';
16
16
  import AngleDoubleUpIcon from '@patternfly/react-icons/dist/js/icons/angle-double-up-icon';
17
17
  import { ErrorBoundary, ToastNotification, useBreakpoint, useDocumentTitle, useForceUpdate, usePrevious, } from '@rh-support/components';
18
- import { fetchAllStatuses, fetchCaseGroupsForSSO, fetchCaseSeverities, fetchCaseTypes, fetchProducts, GlobalMetadataDispatchContext, GlobalMetadataStateContext, setUserPreferences, updateUserPreferences, UserPreferencesKeys, } from '@rh-support/react-context';
18
+ import { CSSUserModal, fetchAllStatuses, fetchCaseGroupsForSSO, fetchCaseSeverities, fetchCaseTypes, fetchProducts, GlobalMetadataDispatchContext, GlobalMetadataStateContext, setUserPreferences, updateCaseListTraditionalSupportAgreed, updateUserPreferences, useGlobalDispatchContext, UserPreferencesKeys, } from '@rh-support/react-context';
19
19
  import { getStringifiedParams, getUrlParsedParams, haventLoadedMetadata, haventLoadedProductsMetadata, pendoTrackEvent, solrResponseToFacetFields, solrResponseToPivotFields, } from '@rh-support/utils';
20
20
  import get from 'lodash/get';
21
21
  import isEmpty from 'lodash/isEmpty';
@@ -49,7 +49,8 @@ export function CaseList(props) {
49
49
  const { caseList, pivotValues, isFetching, filterValuesFromFacetResponse, currentQuery } = useCaseListStateContext();
50
50
  const CaseListDispatch = useCaseListDispatchContext();
51
51
  const breakPoint = useBreakpoint();
52
- const { globalMetadataState, globalMetadataState: { caseGroups, loggedInUserJwtToken, loggedInUserRights, loggedInUsersAccount, userPreferences, managedAccounts, bookmarkedAccounts, bookmarkedGroupAccounts, allCaseTypes, allCaseSeverities, allCaseStatuses, allProducts, }, } = useContext(GlobalMetadataStateContext);
52
+ const { globalMetadataState, globalMetadataState: { caseGroups, loggedInUserJwtToken, loggedInUserRights, loggedInUsersAccount, userPreferences, managedAccounts, bookmarkedAccounts, bookmarkedGroupAccounts, allCaseTypes, allCaseSeverities, allCaseStatuses, allProducts, caseListTraditionalSupportAgreed, }, } = useContext(GlobalMetadataStateContext);
53
+ const globalDispatchContext = useGlobalDispatchContext();
53
54
  const location = useLocation();
54
55
  const searchParams = getUrlParsedParams(location.search);
55
56
  const queryFromUrl = searchParams[FILTER_URL_QUERY_SEARCH_PARAM];
@@ -309,6 +310,9 @@ export function CaseList(props) {
309
310
  isCaseListFilterPanelExanded && isXLScreen && isBasicSearchMode && toggleFilterSection(true);
310
311
  // eslint-disable-next-line react-hooks/exhaustive-deps
311
312
  }, [isBasicSearchMode]);
313
+ const onConfirmTraditionalSupportAgreement = () => {
314
+ updateCaseListTraditionalSupportAgreed(globalDispatchContext, true);
315
+ };
312
316
  const displayRHCDAlert = () => {
313
317
  const openClosedCopy = `Only showing cases that were ${RHCDValue} during the selected time range specified in
314
318
  Customer Dashboard. Case counts may vary slightly based on data retention and availability
@@ -328,34 +332,35 @@ export function CaseList(props) {
328
332
  isCaseListFilterPanelExanded && (isXLScreen ? toggleFilterSection(true) : toggleFilterSection(false));
329
333
  // eslint-disable-next-line react-hooks/exhaustive-deps
330
334
  }, [breakPoint]);
331
- return (React.createElement("article", { id: "rh-support-cases", className: "cases-main" },
332
- isSolrSearchDown && (React.createElement("div", null,
333
- React.createElement(Alert, { isInline: true, variant: AlertVariant.warning, component: "p", title: React.createElement(Trans, null,
335
+ return (React.createElement(React.Fragment, null,
336
+ React.createElement(CSSUserModal, { onConfirmTraditionalSupportAgreement: onConfirmTraditionalSupportAgreement, display: !caseListTraditionalSupportAgreed }),
337
+ React.createElement("article", { id: "rh-support-cases", className: "cases-main" },
338
+ isSolrSearchDown && (React.createElement(Alert, { isInline: true, variant: AlertVariant.warning, component: "p", title: React.createElement(Trans, null,
334
339
  "Case search is working with limited functionality. Please check",
335
340
  ' ',
336
341
  React.createElement("a", { href: "https://status.redhat.com", target: "_blank", rel: "noreferrer", "data-tracking-id": "caselist-redirect-status-page" }, "status page"),
337
342
  ' ',
338
- "for details.") }))),
339
- React.createElement("section", { className: "case-search-top" },
340
- !isEmpty(RHCDValue) && isRHCDAlertShown && React.createElement("div", { className: "push-bottom" }, displayRHCDAlert()),
341
- React.createElement("div", { className: "search-wrapper" },
342
- React.createElement("div", { className: "open-case" },
343
- React.createElement(NewCaseButton, { routeProps: props.routeProps })),
344
- React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading case search input') } },
345
- React.createElement(CaseSearch, { defaultSavedSearchName: defaultSavedSearchName }))),
346
- isBasicSearchMode && (React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filter chips') } },
347
- React.createElement(CaseListFilterChips, { productVersionPivotValues: get(pivotValues, SolrPivotKeys.product_version, []), isSolrSearchDown: isSolrSearchDown })))),
348
- React.createElement("section", { className: "case-search-bottom" },
349
- isBasicSearchMode && (React.createElement("aside", { className: `case-search-filters ${((_a = filterSectionRef.current) === null || _a === void 0 ? void 0 : _a.expanded) ? '' : 'collapsed'}` },
350
- React.createElement("h2", { className: "filter-header" }, ((_b = filterSectionRef.current) === null || _b === void 0 ? void 0 : _b.expanded) ? (React.createElement(React.Fragment, null,
351
- React.createElement(Button, { variant: "link", isActive: true, title: t('Collapse filter section'), onClick: onToggleFilterBtnClick, iconPosition: "right", icon: isXLScreen ? React.createElement(AngleDoubleLeftIcon, null) : React.createElement(AngleDoubleUpIcon, null) },
352
- React.createElement("span", null,
353
- React.createElement(Trans, null, "Filters"))))) : (React.createElement(Button, { variant: "link", isActive: false, title: t('Expand filter section'), onClick: onToggleFilterBtnClick, iconPosition: "right", icon: isXLScreen ? React.createElement(AngleDoubleRightIcon, null) : React.createElement(AngleDoubleDownIcon, null) }, isXLScreen ? null : (React.createElement("span", null,
354
- React.createElement(Trans, null, "Filters")))))),
355
- React.createElement("div", { className: "filter-wrapper" },
356
- React.createElement("pfe-collapse-panel", { id: "case-filters-panel", "pfe-animation": "false", ref: filterSectionRef },
357
- React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filters') } },
358
- React.createElement(CaseListFilters, { filterValues: filterValuesFromFacetResponse, allCaseTypes: allCaseTypes, allCaseStatuses: allCaseStatuses, allCaseSeverities: allCaseSeverities, allProducts: allProducts, isSolrSearchDown: isSolrSearchDown })))))),
359
- React.createElement("section", { className: "case-search-table" },
360
- React.createElement(CaseListTable, { caseList: caseList, caseGroups: caseGroups.data || [], loggedInUserRights: loggedInUserRights.data, sortInfo: filterState.sortInfo, paginationInfo: filterState.paginationInfo, isCaseListPageLoading: isFetching, hasError: hasError, isSolrDown: isSolrSearchDown })))));
343
+ "for details.") })),
344
+ React.createElement("section", { className: "case-search-top" },
345
+ !isEmpty(RHCDValue) && isRHCDAlertShown && React.createElement("div", { className: "push-bottom" }, displayRHCDAlert()),
346
+ React.createElement("div", { className: "search-wrapper" },
347
+ React.createElement("div", { className: "open-case" },
348
+ React.createElement(NewCaseButton, { routeProps: props.routeProps })),
349
+ React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading case search input') } },
350
+ React.createElement(CaseSearch, { defaultSavedSearchName: defaultSavedSearchName }))),
351
+ isBasicSearchMode && (React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filter chips') } },
352
+ React.createElement(CaseListFilterChips, { productVersionPivotValues: get(pivotValues, SolrPivotKeys.product_version, []), isSolrSearchDown: isSolrSearchDown })))),
353
+ React.createElement("section", { className: "case-search-bottom" },
354
+ isBasicSearchMode && (React.createElement("aside", { className: `case-search-filters ${((_a = filterSectionRef.current) === null || _a === void 0 ? void 0 : _a.expanded) ? '' : 'collapsed'}` },
355
+ React.createElement("h2", { className: "filter-header" }, ((_b = filterSectionRef.current) === null || _b === void 0 ? void 0 : _b.expanded) ? (React.createElement(React.Fragment, null,
356
+ React.createElement(Button, { variant: "link", isActive: true, title: t('Collapse filter section'), "data-tracking-id": "collapse-case-list-filter", onClick: onToggleFilterBtnClick, iconPosition: "right", icon: isXLScreen ? React.createElement(AngleDoubleLeftIcon, null) : React.createElement(AngleDoubleUpIcon, null) },
357
+ React.createElement("span", null,
358
+ React.createElement(Trans, null, "Filters"))))) : (React.createElement(Button, { variant: "link", isActive: false, title: t('Expand filter section'), "data-tracking-id": "expand-case-list-filter", onClick: onToggleFilterBtnClick, iconPosition: "right", icon: isXLScreen ? React.createElement(AngleDoubleRightIcon, null) : React.createElement(AngleDoubleDownIcon, null) }, isXLScreen ? null : (React.createElement("span", null,
359
+ React.createElement(Trans, null, "Filters")))))),
360
+ React.createElement("div", { className: "filter-wrapper" },
361
+ React.createElement("pfe-collapse-panel", { id: "case-filters-panel", "pfe-animation": "false", ref: filterSectionRef },
362
+ React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filters') } },
363
+ React.createElement(CaseListFilters, { filterValues: filterValuesFromFacetResponse, allCaseTypes: allCaseTypes, allCaseStatuses: allCaseStatuses, allCaseSeverities: allCaseSeverities, allProducts: allProducts, isSolrSearchDown: isSolrSearchDown })))))),
364
+ React.createElement("section", { className: "case-search-table" },
365
+ React.createElement(CaseListTable, { caseList: caseList, caseGroups: caseGroups.data || [], loggedInUserRights: loggedInUserRights.data, sortInfo: filterState.sortInfo, paginationInfo: filterState.paginationInfo, isCaseListPageLoading: isFetching, hasError: hasError, isSolrDown: isSolrSearchDown }))))));
361
366
  }
@@ -98,6 +98,6 @@ export function AccountsBookmarkedGroupFilter(props) {
98
98
  return null;
99
99
  }
100
100
  return (React.createElement("div", { className: "pf-v5-c-select" },
101
- React.createElement("label", { htmlFor: "case-list-group-filter" }, canAccessManagedAccounts ? t('Accounts') : t(filterNamesMap[SolrKeys.accountNumber])),
102
- React.createElement(Select, { variant: SelectVariant.typeaheadMulti, onToggle: (_event, open) => onBookmarksToggle(open), onSelect: onBookmarksSelect, onClear: onBookmarksClear, isOpen: isOpen, onFilter: onBookmarksFilter, placeholderText: getDropdownBtnPlaceholder(t(canAccessManagedAccounts ? 'Select an account' : 'Search for a bookmark'), canAccessManagedAccounts ? selectedAccounts : selectedBookmarks, '', dropdownOptions.length, canAccessManagedAccounts ? t('All accounts') : t('All bookmarks')), "data-tracking-id": "accounts-filter", id: "case-list-group-filter" }, getBookmarksOptions(dropdownOptions))));
101
+ React.createElement("label", { htmlFor: "case-list-account-filter", className: "case-list-account-filter-label" }, canAccessManagedAccounts ? t('Accounts') : t(filterNamesMap[SolrKeys.accountNumber])),
102
+ React.createElement(Select, { variant: SelectVariant.typeaheadMulti, onToggle: (_event, open) => onBookmarksToggle(open), onSelect: onBookmarksSelect, onClear: onBookmarksClear, isOpen: isOpen, onFilter: onBookmarksFilter, placeholderText: getDropdownBtnPlaceholder(t(canAccessManagedAccounts ? 'Select an account' : 'Search for a bookmark'), canAccessManagedAccounts ? selectedAccounts : selectedBookmarks, '', dropdownOptions.length, canAccessManagedAccounts ? t('All accounts') : t('All bookmarks')), "data-tracking-id": "accounts-filter", id: "case-list-account-filter" }, getBookmarksOptions(dropdownOptions))));
103
103
  }
@@ -209,7 +209,7 @@ export function CreatorSsoNameFilter() {
209
209
  React.createElement(TextInputGroupMain, { value: externalQuery, onClick: onExternalToggle, onKeyDown: onInputKeyDown, placeholder: getDropdownBtnPlaceholder(t('Search for a name'), selectedExternalContacts.map((i) => i.label), ' ', filteredOptions.length + dropdownHeader.length, t('All contacts')), onChange: onExternalQueryChange, isExpanded: isExternalOpen, innerRef: externalInputRef, "aria-controls": "external-ssousername-filter", role: "combobox" }),
210
210
  React.createElement(TextInputGroupUtilities, null, !isEmpty(externalQuery) && (React.createElement(Button, { variant: "plain", onClick: () => setExternalQuery(''), isDisabled: isFetchingExternalContacts, "aria-label": t('Clear') }, isFetchingExternalContacts ? (React.createElement(LoadingIndicator, { show: true, size: "sm" })) : (React.createElement(TimesCircleIcon, { "aria-hidden": true }))))))));
211
211
  return (React.createElement("div", null,
212
- React.createElement("label", { htmlFor: "case-list-username-filter" },
212
+ React.createElement("label", { htmlFor: "case-list-username-filter", className: "case-list-username-filter-label" },
213
213
  React.createElement(Trans, null, filterNamesMap['usernameFilterTitle'])),
214
214
  !loggedInUserRights.data.isInternal() ? (React.createElement(Select, { id: "external-ssousername-filter", "data-tracking-id": "external-ssousername-filter", isOpen: isExternalOpen, onOpenChange: () => setIsExternalOpen(false), toggle: externalToggle, popperProps: { direction: 'down', enableFlip: false }, isScrollable: true, onSelect: (_e, v) => onSelectExternal(v) },
215
215
  React.createElement(SelectList, null, filteredExternalList))) : (React.createElement(InternalSsoNameFilter, null))));
@@ -1 +1 @@
1
- {"version":3,"file":"GroupsFilter.d.ts","sourceRoot":"","sources":["../../../../../src/components/case-list/case-list-filters/GroupsFilter.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAmB1C,wBAAgB,YAAY,sBA6D3B"}
1
+ {"version":3,"file":"GroupsFilter.d.ts","sourceRoot":"","sources":["../../../../../src/components/case-list/case-list-filters/GroupsFilter.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAShF,wBAAgB,YAAY,sBA2P3B"}
@@ -1,11 +1,13 @@
1
- import { MultiSelectDropDownList } from '@rh-support/components';
1
+ import { Button, Divider, MenuToggle, Select, SelectList, SelectOption, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
2
+ import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon';
2
3
  import { GlobalMetadataStateContext } from '@rh-support/react-context';
3
4
  import { ability, resourceActions, resources } from '@rh-support/user-permissions';
4
- import { getDropdownBtnPlaceholder, toOptions } from '@rh-support/utils';
5
- import React, { useContext } from 'react';
5
+ import { getDropdownBtnPlaceholder } from '@rh-support/utils';
6
+ import isEmpty from 'lodash/isEmpty';
7
+ import isUndefined from 'lodash/isUndefined';
8
+ import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
6
9
  import { Trans, useTranslation } from 'react-i18next';
7
10
  import { Link } from 'react-router-dom';
8
- import { FILTER_SEARCHABLE_MODE_LIMIT } from '../../../enums/caseSearch';
9
11
  import { SolrKeys } from '../../../enums/filters';
10
12
  import { filterNamesMap } from '../../../utils/constants';
11
13
  import { CaseListFilterDispatchContext, CaseListFilterStateContext } from '../CaseListFilterContext';
@@ -15,30 +17,157 @@ export function GroupsFilter() {
15
17
  const { globalMetadataState: { caseGroups }, } = useContext(GlobalMetadataStateContext);
16
18
  const { filterInfo } = useContext(CaseListFilterStateContext);
17
19
  const dispatch = useContext(CaseListFilterDispatchContext);
20
+ const [inputValue, setInputValue] = useState('');
21
+ const [focusedItemIndex, setFocusedItemIndex] = useState(null);
22
+ const [activeItem, setActiveItem] = useState(null);
23
+ const list = [
24
+ ...(caseGroups.data ? caseGroups === null || caseGroups === void 0 ? void 0 : caseGroups.data.map((group) => ({ value: group.name, key: group.groupNum })) : []),
25
+ ];
26
+ const [selectOptions, setSelectOptions] = useState(list);
18
27
  const canViewManageTab = ability.can(resourceActions.READ, resources.MANAGE);
19
28
  const canViewCaseGroups = ability.can(resourceActions.READ, resources.CASE_GROUPS) && canViewManageTab;
20
- const onGroupFilterChange = (selectedGroups) => {
21
- selectedGroups = selectedGroups.map((i) => i.value);
22
- updateFilter(dispatch, { filterKey: SolrKeys.group, values: selectedGroups });
29
+ const [isOpen, setIsOpen] = useState(false);
30
+ const [selectedItems, setSelectedItems] = useState({});
31
+ const textInputRef = useRef();
32
+ const onToggleClick = () => {
33
+ setIsOpen(!isOpen);
23
34
  };
24
- const isFilterSearchable = caseGroups.data && caseGroups.data.length > FILTER_SEARCHABLE_MODE_LIMIT;
25
- const list = [
26
- ...(caseGroups.data ? caseGroups.data.map((group) => ({ value: group.name, key: group.groupNum })) : []),
27
- {
28
- children: canViewCaseGroups ? (React.createElement(React.Fragment, null,
29
- React.createElement("div", { className: "pf-v5-c-divider", role: "separator" }),
30
- React.createElement(Link, { className: "cta cta-link pf-v5-c-select__menu-item", to: "/manage/groups" },
31
- React.createElement(Trans, null, "Manage groups")))) : (React.createElement(React.Fragment, null)),
32
- isNotSearchable: true,
33
- isNonActionable: true,
34
- isNotSelectable: true,
35
- },
36
- ];
37
- return (React.createElement(MultiSelectDropDownList, { placeholder: getDropdownBtnPlaceholder(t('Select a group'), filterInfo[SolrKeys.group], ' ', (caseGroups.data || []).length, t('All selected')), "data-tracking-id": "groups-filter", id: "case-list-group-filter", title: t(filterNamesMap[SolrKeys.group]), label: t(filterNamesMap[SolrKeys.group]), searchable: isFilterSearchable, onChange: onGroupFilterChange, selectedItems: toOptions(filterInfo[SolrKeys.group], { labelKey: 'value' }), list: toOptions(list, {
38
- labelKey: 'value',
39
- childrenKey: 'children',
40
- nonSearchableItemKey: 'isNotSearchable',
41
- nonActionableItemKey: 'isNonActionable',
42
- nonSelectableItemKey: 'isNotSelectable',
43
- }) }));
35
+ const onSelect = (option) => {
36
+ const prevSelectedGroups = Object.keys(selectedItems).filter((item) => selectedItems[item] && item);
37
+ if (selectedItems[option.value]) {
38
+ setSelectedItems((prevData) => (Object.assign(Object.assign({}, prevData), { [option.value]: !prevData[option.value] })));
39
+ const indexOfGroup = prevSelectedGroups.indexOf(option.value);
40
+ prevSelectedGroups.splice(indexOfGroup, 1);
41
+ }
42
+ else {
43
+ setSelectedItems((prevData) => (Object.assign(Object.assign({}, prevData), { [option.value]: true })));
44
+ prevSelectedGroups.push(option.value);
45
+ }
46
+ const mapValueToKey = (value) => {
47
+ const selectedItem = list.find((item) => item.value === value);
48
+ return selectedItem;
49
+ };
50
+ const updatedFilterValues = prevSelectedGroups.map((item) => mapValueToKey(item));
51
+ updateFilter(dispatch, {
52
+ filterKey: SolrKeys.group,
53
+ values: updatedFilterValues,
54
+ });
55
+ };
56
+ const handleMenuArrowKeys = (key) => {
57
+ let indexToFocus;
58
+ if (isOpen) {
59
+ if (key === 'ArrowUp') {
60
+ // When no index is set or at the first index, focus to the last, otherwise decrement focus index
61
+ if (focusedItemIndex === null || focusedItemIndex === 0) {
62
+ indexToFocus = (list === null || list === void 0 ? void 0 : list.length) - 1;
63
+ }
64
+ else {
65
+ indexToFocus = focusedItemIndex - 1;
66
+ }
67
+ }
68
+ if (key === 'ArrowDown') {
69
+ // When no index is set or at the last index, focus to the first, otherwise increment focus index
70
+ if (focusedItemIndex === null || focusedItemIndex === (list === null || list === void 0 ? void 0 : list.length) - 1) {
71
+ indexToFocus = 0;
72
+ }
73
+ else {
74
+ indexToFocus = focusedItemIndex + 1;
75
+ }
76
+ }
77
+ setFocusedItemIndex(indexToFocus);
78
+ const focusedItem = list[indexToFocus];
79
+ setActiveItem(`select-multi-typeahead-checkbox-${focusedItem === null || focusedItem === void 0 ? void 0 : focusedItem.value.replace(' ', '-')}`);
80
+ }
81
+ };
82
+ const onInputKeyDown = (event) => {
83
+ const focusedItem = focusedItemIndex ? list[focusedItemIndex] : list[0];
84
+ switch (event.key) {
85
+ // Select the first available option
86
+ case 'Enter':
87
+ if (!isOpen) {
88
+ setIsOpen((prevIsOpen) => !prevIsOpen);
89
+ }
90
+ else if (isOpen && (focusedItem === null || focusedItem === void 0 ? void 0 : focusedItem.value) !== 'no results') {
91
+ onSelect(focusedItem === null || focusedItem === void 0 ? void 0 : focusedItem.value);
92
+ }
93
+ break;
94
+ case 'Tab':
95
+ case 'Escape':
96
+ setIsOpen(false);
97
+ setActiveItem(null);
98
+ break;
99
+ case 'ArrowUp':
100
+ case 'ArrowDown':
101
+ event.preventDefault();
102
+ handleMenuArrowKeys(event.key);
103
+ break;
104
+ }
105
+ };
106
+ const onTextInputChange = (_event, value) => {
107
+ setInputValue(value);
108
+ };
109
+ const placeholder = getDropdownBtnPlaceholder(t('Select a group'), filterInfo[SolrKeys.group], '', (caseGroups.data || []).length, t('All selected'));
110
+ const onClick = () => {
111
+ var _a;
112
+ setInputValue('');
113
+ setSelectedItems({});
114
+ updateFilter(dispatch, {
115
+ filterKey: SolrKeys.group,
116
+ values: [],
117
+ });
118
+ (_a = textInputRef === null || textInputRef === void 0 ? void 0 : textInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
119
+ };
120
+ const toggle = (toggleRef) => (React.createElement(MenuToggle, { variant: "typeahead", onClick: onToggleClick, innerRef: toggleRef, isExpanded: isOpen, isFullWidth: true },
121
+ React.createElement(TextInputGroup, { isPlain: true },
122
+ React.createElement(TextInputGroupMain, Object.assign({ value: inputValue, onClick: onToggleClick, onChange: onTextInputChange, onKeyDown: onInputKeyDown, id: "multi-typeahead-select-checkbox-input", autoComplete: "off", innerRef: textInputRef, placeholder: placeholder }, (activeItem && { 'aria-activedescendant': activeItem }), { role: "combobox", isExpanded: isOpen, "aria-controls": "select-multi-typeahead-checkbox-listbox" })),
123
+ Object.keys(selectedItems).filter((key) => selectedItems[key] === true).length ? (React.createElement(TextInputGroupUtilities, null,
124
+ React.createElement(Button, { variant: "plain", onClick: onClick, "aria-label": "Clear input value" },
125
+ React.createElement(TimesIcon, { "aria-hidden": true })))) : (''))));
126
+ const dropdownOptions = useMemo(() => {
127
+ return (!isEmpty(selectOptions) ? selectOptions : list).map((option, index) => !isUndefined(option.value) && (React.createElement(SelectOption, { key: option.key, value: option, hasCheckbox: true, isSelected: selectedItems[option.value], isFocused: focusedItemIndex !== null && focusedItemIndex === index, id: `select-multi-typeahead-${option.value.replace(' ', '-')}` }, option.value)));
128
+ // eslint-disable-next-line react-hooks/exhaustive-deps
129
+ }, [selectedItems, caseGroups === null || caseGroups === void 0 ? void 0 : caseGroups.data, selectOptions, focusedItemIndex]);
130
+ useEffect(() => {
131
+ let newSelectOptions = list;
132
+ // Filter menu items based on the text input value when one exists
133
+ if (inputValue) {
134
+ newSelectOptions = list.filter((option) => String(option === null || option === void 0 ? void 0 : option.value).toLowerCase().startsWith(inputValue.toLowerCase()));
135
+ // When no options are found after filtering, display 'No results found'
136
+ if (!newSelectOptions.length) {
137
+ newSelectOptions = [{ isDisabled: false, children: `No results found` }];
138
+ }
139
+ // Open the menu when the input value changes and the new value is not empty
140
+ if (!isOpen) {
141
+ setIsOpen(true);
142
+ }
143
+ }
144
+ setSelectOptions(newSelectOptions);
145
+ setFocusedItemIndex(null);
146
+ setActiveItem(null);
147
+ // eslint-disable-next-line react-hooks/exhaustive-deps
148
+ }, [inputValue]);
149
+ useEffect(() => {
150
+ var _a;
151
+ if (isEmpty(filterInfo[SolrKeys.group])) {
152
+ setSelectedItems({});
153
+ }
154
+ else {
155
+ const selectedGroups = (_a = filterInfo[SolrKeys.group]) === null || _a === void 0 ? void 0 : _a.reduce((selection, group) => {
156
+ selection[group === null || group === void 0 ? void 0 : group.value] = true;
157
+ return selection;
158
+ }, {});
159
+ setSelectedItems(selectedGroups);
160
+ }
161
+ // eslint-disable-next-line react-hooks/exhaustive-deps
162
+ }, [filterInfo[SolrKeys.group]]);
163
+ return (React.createElement("div", { className: "group-filter" },
164
+ React.createElement("label", { htmlFor: "case-list-group-filter", className: "pf-v5-u-mb-sm group-filter-label" }, t(filterNamesMap[SolrKeys.group])),
165
+ React.createElement("div", { className: "pf-v5-c-select" },
166
+ React.createElement(Select, { role: "menu", "data-tracking-id": "groups-filter", id: "case-list-group-filter", title: t(filterNamesMap[SolrKeys.group]), isOpen: isOpen, selected: selectedItems, onSelect: (_e, v) => onSelect(v), onOpenChange: (nextOpen) => setIsOpen(nextOpen), popperProps: { direction: 'down', enableFlip: false }, toggle: toggle, isScrollable: true },
167
+ React.createElement(SelectList, null, dropdownOptions),
168
+ canViewCaseGroups && (React.createElement(React.Fragment, null,
169
+ React.createElement(Divider, null),
170
+ React.createElement(SelectList, null,
171
+ React.createElement(Link, { className: "cta cta-link pf-v5-c-select__menu-item", to: "/manage/groups" },
172
+ React.createElement(Trans, null, "Manage groups")))))))));
44
173
  }
@@ -9,9 +9,28 @@
9
9
  .pf-v5-c-select__menu {
10
10
  z-index: 1;
11
11
  }
12
+ li.pf-v5-c-menu__list-item {
13
+ font-size: 16px;
14
+ font-weight: 400;
15
+ }
12
16
  }
13
17
 
14
18
  .pf-v5-c-menu__group-title {
15
19
  margin: 0;
16
20
  padding: 0;
17
21
  }
22
+
23
+ label.pf-v5-u-mb-sm.group-filter-label,
24
+ .case-list-account-filter-label,
25
+ .case-list-username-filter-label {
26
+ font-size: 14px !important;
27
+ }
28
+
29
+ .group-filter {
30
+ span.pf-v5-c-menu-toggle__text {
31
+ color: var(--pf-v5-global--palette--black-600);
32
+ }
33
+ #case-list-group-filter {
34
+ z-index: 9 !important;
35
+ }
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/cases",
3
- "version": "2.1.69",
3
+ "version": "2.1.71",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org"
@@ -43,8 +43,8 @@
43
43
  "@patternfly/patternfly": "5.1.0",
44
44
  "@patternfly/react-core": "5.1.1",
45
45
  "@patternfly/react-table": "5.1.1",
46
- "@rh-support/components": "2.1.53",
47
- "@rh-support/react-context": "2.1.59",
46
+ "@rh-support/components": "2.1.55",
47
+ "@rh-support/react-context": "2.1.61",
48
48
  "@rh-support/types": "2.0.3",
49
49
  "@rh-support/user-permissions": "2.1.39",
50
50
  "@rh-support/utils": "2.1.29",
@@ -96,5 +96,5 @@
96
96
  "defaults and supports es6-module",
97
97
  "maintained node versions"
98
98
  ],
99
- "gitHead": "d579286a00d09356cd07729b5750176ad8e3c090"
99
+ "gitHead": "78f502e76b6377132fe700672387f0da8f6d3dc3"
100
100
  }