@rh-support/cases 2.6.228 → 2.6.230

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/lib/esm/components/case/NewCaseButton.js +1 -1
  2. package/lib/esm/components/case-list/CaseList.d.ts +0 -7
  3. package/lib/esm/components/case-list/CaseList.d.ts.map +1 -1
  4. package/lib/esm/components/case-list/CaseList.js +374 -137
  5. package/lib/esm/components/case-list/CaseListContext.d.ts.map +1 -1
  6. package/lib/esm/components/case-list/CaseListContext.js +5 -2
  7. package/lib/esm/components/case-list/CaseListFilterContext.d.ts.map +1 -1
  8. package/lib/esm/components/case-list/CaseListFilterContext.js +2 -1
  9. package/lib/esm/components/case-list/CaseListFilterHelpers.d.ts +3 -2
  10. package/lib/esm/components/case-list/CaseListFilterHelpers.d.ts.map +1 -1
  11. package/lib/esm/components/case-list/CaseListFilterHelpers.js +19 -6
  12. package/lib/esm/components/case-list/CaseListFilterReducer.d.ts +36 -4
  13. package/lib/esm/components/case-list/CaseListFilterReducer.d.ts.map +1 -1
  14. package/lib/esm/components/case-list/CaseListFilterReducer.js +6 -12
  15. package/lib/esm/components/case-list/CaseListReducer.d.ts +22 -10
  16. package/lib/esm/components/case-list/CaseListReducer.d.ts.map +1 -1
  17. package/lib/esm/components/case-list/CaseListReducer.js +25 -7
  18. package/lib/esm/components/case-list/case-list-filters/AccountsFilter.d.ts.map +1 -1
  19. package/lib/esm/components/case-list/case-list-filters/AccountsFilter.js +18 -11
  20. package/lib/esm/components/case-list/case-list-filters/AdditionalFilters.d.ts.map +1 -1
  21. package/lib/esm/components/case-list/case-list-filters/AdditionalFilters.js +20 -4
  22. package/lib/esm/components/case-list/case-list-filters/CaseLabelsFilter.d.ts +3 -0
  23. package/lib/esm/components/case-list/case-list-filters/CaseLabelsFilter.d.ts.map +1 -0
  24. package/lib/esm/components/case-list/case-list-filters/CaseLabelsFilter.js +178 -0
  25. package/lib/esm/components/case-list/case-list-filters/CaseListFilterChips.d.ts +1 -7
  26. package/lib/esm/components/case-list/case-list-filters/CaseListFilterChips.d.ts.map +1 -1
  27. package/lib/esm/components/case-list/case-list-filters/CaseListFilterChips.js +12 -16
  28. package/lib/esm/components/case-list/case-list-filters/CaseListFilters.d.ts +2 -5
  29. package/lib/esm/components/case-list/case-list-filters/CaseListFilters.d.ts.map +1 -1
  30. package/lib/esm/components/case-list/case-list-filters/CaseListFilters.js +14 -13
  31. package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilter.d.ts.map +1 -1
  32. package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilter.js +21 -14
  33. package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilterChip.d.ts.map +1 -1
  34. package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilterChip.js +3 -0
  35. package/lib/esm/components/case-list/case-list-filters/GroupsFilter.d.ts +11 -1
  36. package/lib/esm/components/case-list/case-list-filters/GroupsFilter.d.ts.map +1 -1
  37. package/lib/esm/components/case-list/case-list-filters/GroupsFilter.js +90 -70
  38. package/lib/esm/components/case-list/case-list-filters/ProductFilterChip.d.ts +1 -3
  39. package/lib/esm/components/case-list/case-list-filters/ProductFilterChip.d.ts.map +1 -1
  40. package/lib/esm/components/case-list/case-list-filters/ProductFilterChip.js +2 -2
  41. package/lib/esm/components/case-list/case-list-filters/ProductsFilter.d.ts +5 -4
  42. package/lib/esm/components/case-list/case-list-filters/ProductsFilter.d.ts.map +1 -1
  43. package/lib/esm/components/case-list/case-list-filters/ProductsFilter.js +15 -54
  44. package/lib/esm/components/case-list/case-list-filters/SeverityFilter.d.ts +0 -3
  45. package/lib/esm/components/case-list/case-list-filters/SeverityFilter.d.ts.map +1 -1
  46. package/lib/esm/components/case-list/case-list-filters/SeverityFilter.js +18 -44
  47. package/lib/esm/components/case-list/case-list-filters/StatusFilter.d.ts +0 -3
  48. package/lib/esm/components/case-list/case-list-filters/StatusFilter.d.ts.map +1 -1
  49. package/lib/esm/components/case-list/case-list-filters/StatusFilter.js +23 -49
  50. package/lib/esm/components/case-list/case-list-filters/VersionsFilter.d.ts +1 -3
  51. package/lib/esm/components/case-list/case-list-filters/VersionsFilter.d.ts.map +1 -1
  52. package/lib/esm/components/case-list/case-list-filters/VersionsFilter.js +60 -59
  53. package/lib/esm/components/case-list/case-list-table/ArchivedCaseLabel.d.ts +3 -0
  54. package/lib/esm/components/case-list/case-list-table/ArchivedCaseLabel.d.ts.map +1 -0
  55. package/lib/esm/components/case-list/case-list-table/ArchivedCaseLabel.js +8 -0
  56. package/lib/esm/components/case-list/case-list-table/CaseListLabelGroup.d.ts +9 -0
  57. package/lib/esm/components/case-list/case-list-table/CaseListLabelGroup.d.ts.map +1 -0
  58. package/lib/esm/components/case-list/case-list-table/CaseListLabelGroup.js +105 -0
  59. package/lib/esm/components/case-list/case-list-table/CaseListTable.d.ts +10 -3
  60. package/lib/esm/components/case-list/case-list-table/CaseListTable.d.ts.map +1 -1
  61. package/lib/esm/components/case-list/case-list-table/CaseListTable.js +98 -84
  62. package/lib/esm/components/case-list/case-list-table/CaseListTableRow.d.ts +33 -0
  63. package/lib/esm/components/case-list/case-list-table/CaseListTableRow.d.ts.map +1 -0
  64. package/lib/esm/components/case-list/case-list-table/CaseListTableRow.js +51 -0
  65. package/lib/esm/components/case-list/case-list-table/CaseListTableSkeletonRow.d.ts +9 -0
  66. package/lib/esm/components/case-list/case-list-table/CaseListTableSkeletonRow.d.ts.map +1 -0
  67. package/lib/esm/components/case-list/case-list-table/CaseListTableSkeletonRow.js +10 -0
  68. package/lib/esm/components/case-list/case-list-table/DownloadCSVFileModal.d.ts +0 -5
  69. package/lib/esm/components/case-list/case-list-table/DownloadCSVFileModal.d.ts.map +1 -1
  70. package/lib/esm/components/case-list/case-list-table/DownloadCSVFileModal.js +51 -70
  71. package/lib/esm/components/case-list/case-list-table/ExportCaseListCSV.d.ts.map +1 -1
  72. package/lib/esm/components/case-list/case-list-table/ExportCaseListCSV.js +5 -15
  73. package/lib/esm/components/case-list/case-list-table/SeverityLabel.js +1 -1
  74. package/lib/esm/components/case-list/case-list-table/TableActionsDropdown.d.ts.map +1 -1
  75. package/lib/esm/components/case-list/case-list-table/TableActionsDropdown.js +2 -3
  76. package/lib/esm/components/case-list/case-list-table/table-column-selector/TableColumnSelector.d.ts.map +1 -1
  77. package/lib/esm/components/case-list/case-list-table/table-column-selector/TableColumnSelector.js +1 -0
  78. package/lib/esm/components/case-list/case-search/AdvanceSearchToggleButton.d.ts +8 -0
  79. package/lib/esm/components/case-list/case-search/AdvanceSearchToggleButton.d.ts.map +1 -0
  80. package/lib/esm/components/case-list/case-search/AdvanceSearchToggleButton.js +8 -0
  81. package/lib/esm/components/case-list/case-search/BookmarkedSearchesSelector.d.ts.map +1 -1
  82. package/lib/esm/components/case-list/case-search/BookmarkedSearchesSelector.js +15 -2
  83. package/lib/esm/components/case-list/case-search/CaseSearch.d.ts.map +1 -1
  84. package/lib/esm/components/case-list/case-search/CaseSearch.js +55 -24
  85. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAccountSection.d.ts +10 -0
  86. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAccountSection.d.ts.map +1 -0
  87. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAccountSection.js +29 -0
  88. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAuditsSection.d.ts +10 -0
  89. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAuditsSection.d.ts.map +1 -0
  90. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAuditsSection.js +16 -0
  91. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchCaseSection.d.ts +9 -0
  92. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchCaseSection.d.ts.map +1 -0
  93. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchCaseSection.js +21 -0
  94. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchDateRangeField.d.ts +12 -0
  95. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchDateRangeField.d.ts.map +1 -0
  96. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchDateRangeField.js +31 -0
  97. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchFieldBlock.d.ts +10 -0
  98. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchFieldBlock.d.ts.map +1 -0
  99. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchFieldBlock.js +10 -0
  100. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchModal.d.ts +10 -0
  101. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchModal.d.ts.map +1 -0
  102. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchModal.js +92 -0
  103. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchOwnerSection.d.ts +9 -0
  104. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchOwnerSection.d.ts.map +1 -0
  105. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchOwnerSection.js +20 -0
  106. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchProductSection.d.ts +9 -0
  107. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchProductSection.d.ts.map +1 -0
  108. package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchProductSection.js +28 -0
  109. package/lib/esm/components/case-list/case-search/advance-search-modal/ProductVersionDrilldownSelect.d.ts +9 -0
  110. package/lib/esm/components/case-list/case-search/advance-search-modal/ProductVersionDrilldownSelect.d.ts.map +1 -0
  111. package/lib/esm/components/case-list/case-search/advance-search-modal/ProductVersionDrilldownSelect.js +241 -0
  112. package/lib/esm/components/case-list/case-search/advance-search-modal/SelectableLabelFilter.d.ts +11 -0
  113. package/lib/esm/components/case-list/case-search/advance-search-modal/SelectableLabelFilter.d.ts.map +1 -0
  114. package/lib/esm/components/case-list/case-search/advance-search-modal/SelectableLabelFilter.js +23 -0
  115. package/lib/esm/components/case-list/case-search/useAdvanceSearchParser.d.ts.map +1 -1
  116. package/lib/esm/components/case-list/case-search/useAdvanceSearchParser.js +2 -1
  117. package/lib/esm/css/caseList.css +188 -23
  118. package/lib/esm/css/caseSearch.css +114 -0
  119. package/lib/esm/enums/case.d.ts +13 -5
  120. package/lib/esm/enums/case.d.ts.map +1 -1
  121. package/lib/esm/enums/case.js +23 -3
  122. package/lib/esm/enums/caseSearch.d.ts +3 -0
  123. package/lib/esm/enums/caseSearch.d.ts.map +1 -1
  124. package/lib/esm/enums/caseSearch.js +2 -1
  125. package/lib/esm/enums/filters.d.ts +5 -1
  126. package/lib/esm/enums/filters.d.ts.map +1 -1
  127. package/lib/esm/enums/filters.js +4 -0
  128. package/lib/esm/hooks/useCaseLabels.d.ts +14 -0
  129. package/lib/esm/hooks/useCaseLabels.d.ts.map +1 -0
  130. package/lib/esm/hooks/useCaseLabels.js +50 -0
  131. package/lib/esm/hooks/useCloseCase.d.ts.map +1 -1
  132. package/lib/esm/hooks/useCloseCase.js +38 -21
  133. package/lib/esm/hooks/useExportCaseListCSV.d.ts.map +1 -1
  134. package/lib/esm/hooks/useExportCaseListCSV.js +1 -9
  135. package/lib/esm/hooks/useFilterStateOnLoad.d.ts +1 -1
  136. package/lib/esm/hooks/useFilterStateOnLoad.d.ts.map +1 -1
  137. package/lib/esm/hooks/useFilterStateOnLoad.js +7 -5
  138. package/lib/esm/index.js +1 -0
  139. package/lib/esm/models/caseList.d.ts +1 -0
  140. package/lib/esm/models/caseList.d.ts.map +1 -1
  141. package/lib/esm/test-utils/mockData.d.ts +1 -0
  142. package/lib/esm/test-utils/mockData.d.ts.map +1 -1
  143. package/lib/esm/test-utils/mockData.js +2 -1
  144. package/lib/esm/utils/advanceSearchFormMapper.d.ts +11 -0
  145. package/lib/esm/utils/advanceSearchFormMapper.d.ts.map +1 -0
  146. package/lib/esm/utils/advanceSearchFormMapper.js +71 -0
  147. package/lib/esm/utils/advanceSearchUtils.d.ts +24 -0
  148. package/lib/esm/utils/advanceSearchUtils.d.ts.map +1 -0
  149. package/lib/esm/utils/advanceSearchUtils.js +150 -0
  150. package/lib/esm/utils/caseGroupDefaultFilterUtils.d.ts +12 -0
  151. package/lib/esm/utils/caseGroupDefaultFilterUtils.d.ts.map +1 -0
  152. package/lib/esm/utils/caseGroupDefaultFilterUtils.js +34 -0
  153. package/lib/esm/utils/caseGroupDefaultUtils.d.ts +10 -0
  154. package/lib/esm/utils/caseGroupDefaultUtils.d.ts.map +1 -0
  155. package/lib/esm/utils/caseGroupDefaultUtils.js +20 -0
  156. package/lib/esm/utils/caseListGraphQLUtils.d.ts +28 -0
  157. package/lib/esm/utils/caseListGraphQLUtils.d.ts.map +1 -0
  158. package/lib/esm/utils/caseListGraphQLUtils.js +304 -0
  159. package/lib/esm/utils/caseListMapper.d.ts +6 -0
  160. package/lib/esm/utils/caseListMapper.d.ts.map +1 -0
  161. package/lib/esm/utils/caseListMapper.js +47 -0
  162. package/lib/esm/utils/caseListVariablesBuilder.d.ts +17 -0
  163. package/lib/esm/utils/caseListVariablesBuilder.d.ts.map +1 -0
  164. package/lib/esm/utils/caseListVariablesBuilder.js +535 -0
  165. package/lib/esm/utils/caseSearchUtils.d.ts.map +1 -1
  166. package/lib/esm/utils/caseSearchUtils.js +39 -2
  167. package/lib/esm/utils/constants.d.ts +5 -1
  168. package/lib/esm/utils/constants.d.ts.map +1 -1
  169. package/lib/esm/utils/constants.js +10 -2
  170. package/lib/esm/utils/mockSolrResponse.js +1 -1
  171. package/package.json +10 -8
@@ -9,124 +9,273 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import '../../css/caseList.css';
11
11
  import '../../css/caseSearch.css';
12
+ import { useApolloClient } from '@apollo/client/react';
12
13
  import { Alert, AlertActionCloseButton, AlertVariant, Button } from '@patternfly/react-core';
13
14
  import OpenDrawerRightIcon from '@patternfly/react-icons/dist/js/icons/open-drawer-right-icon';
14
- import { ErrorBoundary, ToastNotification, useBreakpoint, useDocumentTitle, useForceUpdate, usePrevious, } from '@rh-support/components';
15
- import { CSSUserModal, fetchAllStatuses, fetchCaseGroupsForAccount, fetchCaseGroupsForSSO, fetchCaseSeverities, fetchCaseTypes, fetchProducts, GlobalMetadataDispatchContext, GlobalMetadataStateContext, setUserPreferences, updateCaseListTraditionalSupportAgreed, updateUserPreferences, useGlobalDispatchContext, UserPreferencesKeys, } from '@rh-support/react-context';
16
- import { getStringifiedParams, getUrlParsedParams, haventLoadedMetadata, haventLoadedProductsMetadata, solrResponseToFacetFields, solrResponseToPivotFields, } from '@rh-support/utils';
17
- import get from 'lodash/get';
15
+ import { ErrorBoundary, ToastNotification, useBreakpoint, useDocumentTitle, useForceUpdate, } from '@rh-support/components';
16
+ import { CSSUserModal, fetchAllStatuses, fetchCaseGroupsForAccount, fetchCaseGroupsForSSO, fetchCaseSeverities, fetchCaseTypes, fetchProducts, GlobalMetadataDispatchContext, GlobalMetadataStateContext, setTraditionalSupportSessionAgreed, setUserPreferences, updateUserPreferences, useGlobalDispatchContext, UserPreferencesKeys, } from '@rh-support/react-context';
17
+ import { getStringifiedParams, getUrlParsedParams, haventLoadedMetadata, haventLoadedProductsMetadata, pendoTrackEvent, } from '@rh-support/utils';
18
18
  import isEmpty from 'lodash/isEmpty';
19
- import mapValues from 'lodash/mapValues';
19
+ import isEqual from 'lodash/isEqual';
20
20
  import some from 'lodash/some';
21
21
  import React, { useContext, useEffect, useRef, useState } from 'react';
22
22
  import { Trans, useTranslation } from 'react-i18next';
23
+ import { useInView } from 'react-intersection-observer';
23
24
  import { useLocation } from 'react-router-dom';
24
25
  import { CaseSearchQueryType } from '../../enums/caseSearch';
25
- import { SolrPivotKeys } from '../../enums/filters';
26
+ import { SolrKeys } from '../../enums/filters';
26
27
  import { PageTitle } from '../../enums/pageTitle';
28
+ import { useCaseLabels } from '../../hooks/useCaseLabels';
27
29
  import { useFilterStateOnLoad } from '../../hooks/useFilterStateOnLoad';
28
- import { getCaseList } from '../../utils/caseListUtils';
30
+ import { getDefaultGroupFilterSelection, shouldApplyDefaultGroupFilter } from '../../utils/caseGroupDefaultFilterUtils';
31
+ import { clearPageCursors, getCaseListFromGraphQL, loadMoreCases, } from '../../utils/caseListGraphQLUtils';
29
32
  import { createFilterStateFromUrlQuery, createURLQueryFromFilterState, FILTER_URL_CURRENT_PAGE_SEARCH_PARAM, FILTER_URL_PAGE_SIZE_SEARCH_PARAM, FILTER_URL_QUERY_SEARCH_PARAM, FILTER_URL_QUERY_TYPE, } from '../../utils/caseSearchUtils';
33
+ import { UpdatedCaseDataEvent } from '../../utils/constants';
30
34
  import { NewCaseButton } from '../case/NewCaseButton';
31
35
  import { CaseListFilterChips } from './case-list-filters/CaseListFilterChips';
32
36
  import { CaseListFilters } from './case-list-filters/CaseListFilters';
33
37
  import { CaseListTable } from './case-list-table/CaseListTable';
34
38
  import { CaseSearch } from './case-search/CaseSearch';
35
39
  import { useCaseListDispatchContext, useCaseListStateContext } from './CaseListContext';
36
- import { CaseListFilterDispatchContext, CaseListFilterStateContext, initialCaseFilterState, } from './CaseListFilterContext';
37
- import { eligibleSFDCFiltersMultipleValues, isNoFilterApplied, isOnlyDefaultFilterApplied, } from './CaseListFilterHelpers';
40
+ import { CaseListFilterDispatchContext, CaseListFilterStateContext } from './CaseListFilterContext';
41
+ import { isNoFilterApplied, isOnlyDefaultFilterApplied, isOnlyGroupFilterApplied } from './CaseListFilterHelpers';
38
42
  import { updateFilterState } from './CaseListFilterReducer';
39
- import { setCaseList, setCurrentQuery, setFilterValuesFromFacetResponse, setIsFetching, setPivotValues, } from './CaseListReducer';
43
+ import { appendCaseList, setCaseList, setCurrentQuery, setCursorInfo, setIsFetching, setIsLoadingMore, setLoadMoreError, } from './CaseListReducer';
40
44
  export function CaseList(props) {
41
- var _a, _b;
45
+ var _a, _b, _c, _d, _e, _f, _g, _h;
42
46
  const { t } = useTranslation();
43
47
  useDocumentTitle(PageTitle.CASE_LIST);
44
48
  const dispatchToGlobalMetadataReducer = useContext(GlobalMetadataDispatchContext);
45
- const { caseList, pivotValues, isFetching, filterValuesFromFacetResponse, currentQuery } = useCaseListStateContext();
49
+ const { caseList, isFetching, isLoadingMore, hasNextPage, endCursor, currentQuery, loadMoreError, loadMoreRetryCount, } = useCaseListStateContext();
46
50
  const CaseListDispatch = useCaseListDispatchContext();
47
51
  const breakPoint = useBreakpoint();
48
- const { globalMetadataState, globalMetadataState: { caseGroups, loggedInUserJwtToken, loggedInUserRights, loggedInUsersAccount, userPreferences, managedAccounts, bookmarkedAccounts, allCaseTypes, allCaseSeverities, allCaseStatuses, allProducts, caseListTraditionalSupportAgreed, }, } = useContext(GlobalMetadataStateContext);
52
+ const { globalMetadataState, globalMetadataState: { caseGroups, loggedInUser, loggedInUserRights, loggedInUsersAccount, userPreferences, managedAccounts, bookmarkedAccounts, allCaseTypes, allCaseSeverities, allCaseStatuses, allProducts, caseRecordTypes, caseListTraditionalSupportAgreed, hydraUserPreferences, }, } = useContext(GlobalMetadataStateContext);
49
53
  const globalDispatchContext = useGlobalDispatchContext();
54
+ const apolloClient = useApolloClient();
55
+ const includeSecureSupportCases = Boolean(loggedInUsersAccount.data.secureSupport);
50
56
  const location = useLocation();
51
57
  const searchParams = getUrlParsedParams(location.search);
52
58
  const queryFromUrl = searchParams[FILTER_URL_QUERY_SEARCH_PARAM];
53
- const pageSizeFromUrl = parseInt(searchParams[FILTER_URL_PAGE_SIZE_SEARCH_PARAM]);
54
- const currentPageFromUrl = parseInt(searchParams[FILTER_URL_CURRENT_PAGE_SEARCH_PARAM]);
55
59
  const searchType = searchParams[FILTER_URL_QUERY_TYPE];
56
60
  const abortControllerRef = useRef(undefined);
61
+ const lastPushedQueryRef = useRef('');
57
62
  const isXLScreen = breakPoint.xl;
58
63
  const isFirstMount = useRef(true);
64
+ const userDismissedDefaultGroupRef = useRef(false);
65
+ const prevGroupFilterRef = useRef(undefined);
59
66
  const filterSectionRef = useRef(null);
60
67
  const filterState = useContext(CaseListFilterStateContext);
61
68
  const filterDispatch = useContext(CaseListFilterDispatchContext);
62
69
  const forceUpdate = useForceUpdate();
63
70
  const isCaseListFilterPanelExanded = userPreferences.data.isCaseListFilterPanelExanded;
64
71
  const useFilterStateInit = useFilterStateOnLoad();
65
- const isBasicSearchMode = filterState.filterQueryInfo.type === CaseSearchQueryType.BASIC ||
66
- (filterState.filterQueryInfo.type === CaseSearchQueryType.ADVANCED && loggedInUserRights.data.isExternal());
67
- const prevSearchType = usePrevious(filterState.filterQueryInfo.type);
68
- let isSearchTypeChanged = filterState.filterQueryInfo.type !== prevSearchType;
69
72
  const [hasError, setHasError] = useState(null);
70
- const [isSolrSearchDown, setSolrSearchDown] = useState(false);
71
73
  const [defaultSavedSearchName, setDefaultSavedSearchName] = useState('');
72
74
  const [RHCDValue, setRHCDValue] = useState('');
73
75
  const [isRHCDAlertShown, setIsRHCDAlertShown] = useState(true);
76
+ const loadMoreLockRef = useRef(false);
77
+ const loadMoreFnRef = useRef(() => { });
78
+ const loadMoreCooldownRef = useRef(false);
79
+ const loadMoreAbortRef = useRef(null);
80
+ const activeFilterStateRef = useRef(filterState);
81
+ const sentinelElRef = useRef(null);
82
+ const prefetchRef = useRef({
83
+ cursor: '',
84
+ data: null,
85
+ loading: false,
86
+ });
87
+ const { ref: inViewRef, inView } = useInView();
88
+ const sentinelRef = React.useCallback((node) => {
89
+ sentinelElRef.current = node || null;
90
+ inViewRef(node);
91
+ }, [inViewRef]);
92
+ function startPrefetch(cursor) {
93
+ if (!cursor || prefetchRef.current.cursor === cursor)
94
+ return;
95
+ prefetchRef.current = { cursor, data: null, loading: true };
96
+ loadMoreCases(activeFilterStateRef.current, apolloClient, cursor, undefined, includeSecureSupportCases)
97
+ .then((result) => {
98
+ if (prefetchRef.current.cursor === cursor) {
99
+ prefetchRef.current = { cursor, data: result, loading: false };
100
+ }
101
+ })
102
+ .catch(() => {
103
+ if (prefetchRef.current.cursor === cursor) {
104
+ prefetchRef.current = { cursor: '', data: null, loading: false };
105
+ }
106
+ });
107
+ }
108
+ useEffect(() => {
109
+ let ticking = false;
110
+ let triggered = false;
111
+ const onScroll = () => {
112
+ if (ticking)
113
+ return;
114
+ ticking = true;
115
+ requestAnimationFrame(() => {
116
+ ticking = false;
117
+ if (!sentinelElRef.current)
118
+ return;
119
+ const rect = sentinelElRef.current.getBoundingClientRect();
120
+ const isNear = rect.top <= window.innerHeight + 600;
121
+ if (!isNear) {
122
+ triggered = false;
123
+ return;
124
+ }
125
+ if (!triggered && !loadMoreLockRef.current) {
126
+ triggered = true;
127
+ loadMoreFnRef.current();
128
+ }
129
+ });
130
+ };
131
+ window.addEventListener('scroll', onScroll, true);
132
+ return () => window.removeEventListener('scroll', onScroll, true);
133
+ }, []);
134
+ useEffect(() => {
135
+ if (inView && hasNextPage && !isLoadingMore && !loadMoreError) {
136
+ loadMore();
137
+ }
138
+ // eslint-disable-next-line react-hooks/exhaustive-deps
139
+ }, [inView]);
140
+ useEffect(() => {
141
+ if (!isLoadingMore)
142
+ return;
143
+ const handleOffline = () => {
144
+ if (loadMoreAbortRef.current) {
145
+ loadMoreAbortRef.current.abort();
146
+ loadMoreAbortRef.current = null;
147
+ }
148
+ loadMoreLockRef.current = false;
149
+ setLoadMoreError(CaseListDispatch, true, loadMoreRetryCount + 1);
150
+ };
151
+ if (!navigator.onLine) {
152
+ handleOffline();
153
+ return;
154
+ }
155
+ window.addEventListener('offline', handleOffline);
156
+ return () => window.removeEventListener('offline', handleOffline);
157
+ // eslint-disable-next-line react-hooks/exhaustive-deps
158
+ }, [isLoadingMore]);
159
+ useEffect(() => {
160
+ const onClick = (e) => {
161
+ const anchor = e.target.closest('a.btn_slideto[href="#masthead"]');
162
+ if (anchor) {
163
+ e.preventDefault();
164
+ window.scrollTo({ top: 0, behavior: 'smooth' });
165
+ }
166
+ };
167
+ document.addEventListener('click', onClick, true);
168
+ return () => document.removeEventListener('click', onClick, true);
169
+ }, []);
74
170
  function getCases(currentFilterState) {
75
171
  return __awaiter(this, void 0, void 0, function* () {
76
- let showError;
172
+ var _a;
77
173
  try {
78
- setIsFetching(CaseListDispatch, true);
79
- setHasError(false);
80
- if (abortControllerRef.current !== undefined) {
81
- // Cancel the previous request
174
+ if (abortControllerRef.current) {
82
175
  abortControllerRef.current.abort();
83
176
  }
84
- // recreate a new AbortController for each call
85
- let controller = new AbortController();
177
+ const controller = new AbortController();
86
178
  abortControllerRef.current = controller;
87
- const { caseListResponse, isSolrSearchDownSFDCUp, showErrorMessage } = yield getCaseList(currentFilterState, loggedInUserRights.data, loggedInUsersAccount.data, controller.signal);
88
- showError = showErrorMessage;
89
- setSolrSearchDown(isSolrSearchDownSFDCUp);
90
- setFilterValuesFromFacetResponse(CaseListDispatch, solrResponseToFacetFields(caseListResponse));
91
- setPivotValues(CaseListDispatch, solrResponseToPivotFields(caseListResponse));
92
- setCaseList(CaseListDispatch, caseListResponse.response);
179
+ setIsFetching(CaseListDispatch, true);
180
+ setHasError(false);
181
+ prefetchRef.current = { cursor: '', data: null, loading: false };
182
+ loadMoreCooldownRef.current = true;
183
+ activeFilterStateRef.current = currentFilterState;
184
+ const result = yield getCaseListFromGraphQL(currentFilterState, apolloClient, undefined, controller.signal, undefined, includeSecureSupportCases);
185
+ if (controller.signal.aborted) {
186
+ return;
187
+ }
188
+ setCaseList(CaseListDispatch, result.caseListResponse.response);
189
+ setCursorInfo(CaseListDispatch, result.hasNextPage, result.endCursor);
93
190
  setIsFetching(CaseListDispatch, false);
191
+ setTimeout(() => {
192
+ loadMoreCooldownRef.current = false;
193
+ }, 500);
194
+ if (result.hasNextPage && result.endCursor) {
195
+ startPrefetch(result.endCursor);
196
+ }
197
+ if (result.showErrorMessage) {
198
+ setHasError(true);
199
+ ToastNotification.addDangerMessage(t('There was an error loading case data. Please try again.'));
200
+ }
94
201
  }
95
202
  catch (err) {
96
- const isAbortError = err.message && err.message.toLowerCase().indexOf('abort') > -1;
97
- if (!isAbortError) {
98
- setIsFetching(CaseListDispatch, false);
99
- setHasError(true);
100
- showError && ToastNotification.addXHRErrorMessage(err);
203
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError' || ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('aborted'))) {
204
+ return;
101
205
  }
206
+ setIsFetching(CaseListDispatch, false);
207
+ setHasError(true);
208
+ ToastNotification.addXHRErrorMessage(err);
102
209
  }
103
210
  });
104
211
  }
212
+ function loadMore() {
213
+ return __awaiter(this, void 0, void 0, function* () {
214
+ var _a;
215
+ if (loadMoreCooldownRef.current ||
216
+ loadMoreLockRef.current ||
217
+ isLoadingMore ||
218
+ !hasNextPage ||
219
+ !endCursor ||
220
+ loadMoreError)
221
+ return;
222
+ loadMoreLockRef.current = true;
223
+ if (loadMoreAbortRef.current) {
224
+ loadMoreAbortRef.current.abort();
225
+ }
226
+ const controller = new AbortController();
227
+ loadMoreAbortRef.current = controller;
228
+ setIsLoadingMore(CaseListDispatch, true);
229
+ try {
230
+ let result;
231
+ const pf = prefetchRef.current;
232
+ if (pf.cursor === endCursor && pf.data) {
233
+ result = pf.data;
234
+ prefetchRef.current = { cursor: '', data: null, loading: false };
235
+ }
236
+ else {
237
+ prefetchRef.current = { cursor: '', data: null, loading: false };
238
+ result = yield loadMoreCases(activeFilterStateRef.current, apolloClient, endCursor, controller.signal, includeSecureSupportCases);
239
+ }
240
+ if (controller.signal.aborted)
241
+ return;
242
+ setLoadMoreError(CaseListDispatch, false, 0);
243
+ appendCaseList(CaseListDispatch, result.docs, result.hasNextPage, result.endCursor);
244
+ if (result.hasNextPage && result.endCursor) {
245
+ startPrefetch(result.endCursor);
246
+ }
247
+ }
248
+ catch (err) {
249
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError' || ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('aborted')) || controller.signal.aborted) {
250
+ return;
251
+ }
252
+ const nextRetryCount = loadMoreRetryCount + 1;
253
+ setLoadMoreError(CaseListDispatch, true, nextRetryCount);
254
+ console.error('[CaseList] loadMore error:', err);
255
+ }
256
+ finally {
257
+ if (!controller.signal.aborted) {
258
+ loadMoreLockRef.current = false;
259
+ }
260
+ }
261
+ });
262
+ }
263
+ loadMoreFnRef.current = loadMore;
264
+ function retryLoadMore() {
265
+ if (loadMoreAbortRef.current) {
266
+ loadMoreAbortRef.current.abort();
267
+ loadMoreAbortRef.current = null;
268
+ }
269
+ loadMoreLockRef.current = false;
270
+ setLoadMoreError(CaseListDispatch, false, loadMoreRetryCount);
271
+ setTimeout(() => loadMoreFnRef.current(), 0);
272
+ }
105
273
  const toggleFilterSection = (isExpanded) => {
106
274
  if (!filterSectionRef.current)
107
275
  return;
108
276
  filterSectionRef.current.expanded = isExpanded;
109
277
  forceUpdate();
110
278
  };
111
- function saveFilterQueryInUserPreferences() {
112
- if (isNoFilterApplied(filterState))
113
- return;
114
- const type = filterState.filterQueryInfo.type;
115
- const recentSerach = {
116
- filterState: type === CaseSearchQueryType.BASIC ? filterState.filterInfo : {},
117
- sortState: filterState.sortInfo,
118
- queryString: type === CaseSearchQueryType.BASIC
119
- ? filterState.filterQueryInfo.queryString
120
- : filterState.filterQueryInfo.parsedQuery,
121
- type,
122
- };
123
- try {
124
- updateUserPreferences(dispatchToGlobalMetadataReducer, loggedInUserRights.data.getSSOUsername(), [{ key: UserPreferencesKeys.mostRecentSearch, value: JSON.stringify(recentSerach) }], 'add');
125
- }
126
- catch (e) {
127
- console.error('Could not save filter query in user preferences');
128
- }
129
- }
130
279
  const onToggleFilterBtnClick = () => {
131
280
  var _a, _b;
132
281
  toggleFilterSection(!((_a = filterSectionRef.current) === null || _a === void 0 ? void 0 : _a.expanded));
@@ -136,8 +285,7 @@ export function CaseList(props) {
136
285
  };
137
286
  const checkNewCases = () => __awaiter(this, void 0, void 0, function* () {
138
287
  try {
139
- const { caseListResponse, isSolrSearchDownSFDCUp } = yield getCaseList(filterState, loggedInUserRights.data, loggedInUsersAccount.data, null);
140
- setSolrSearchDown(isSolrSearchDownSFDCUp);
288
+ const { caseListResponse } = yield getCaseListFromGraphQL(filterState, apolloClient, undefined, undefined, undefined, includeSecureSupportCases);
141
289
  let changed = false;
142
290
  if (caseListResponse.response.numFound <= filterState.paginationInfo.pageSize &&
143
291
  caseListResponse.response.numFound !== caseList.numFound) {
@@ -159,6 +307,7 @@ export function CaseList(props) {
159
307
  }
160
308
  if (changed && location.pathname === '/case/list') {
161
309
  setCaseList(CaseListDispatch, caseListResponse.response);
310
+ pendoTrackEvent(UpdatedCaseDataEvent);
162
311
  ToastNotification.addSuccessMessage(t('Case data has been updated'));
163
312
  }
164
313
  }
@@ -166,79 +315,150 @@ export function CaseList(props) {
166
315
  console.log(err);
167
316
  }
168
317
  });
318
+ const salesforceAccountId = (_a = loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.salesforceAccountId;
319
+ const { error: caseLabelsFetchError, refetch: refetchCaseLabels } = useCaseLabels(salesforceAccountId);
320
+ const retryCaseListFetch = () => {
321
+ refetchCaseLabels();
322
+ getCases(filterState);
323
+ };
324
+ const loggedInContactId = (_b = loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.data) === null || _b === void 0 ? void 0 : _b.id;
325
+ const loggedInIsOrgAdmin = (_c = loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.data) === null || _c === void 0 ? void 0 : _c.isOrgAdmin;
326
+ const defaultCaseGroupId = (_e = (_d = loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.data) === null || _d === void 0 ? void 0 : _d.defaultCaseGroup) !== null && _e !== void 0 ? _e : null;
327
+ const prevDefaultCaseGroupIdRef = useRef(defaultCaseGroupId);
169
328
  useEffect(() => {
170
329
  var _a;
171
- if (haventLoadedMetadata(caseGroups, (data) => data === undefined)) {
172
- if ((_a = loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.isInternal) {
173
- fetchCaseGroupsForAccount(dispatchToGlobalMetadataReducer, loggedInUsersAccount.data.accountNumber);
174
- }
175
- else {
176
- fetchCaseGroupsForSSO(dispatchToGlobalMetadataReducer, loggedInUserJwtToken.preferred_username);
177
- }
330
+ if (prevDefaultCaseGroupIdRef.current !== defaultCaseGroupId) {
331
+ userDismissedDefaultGroupRef.current = false;
178
332
  }
179
- }, [caseGroups, dispatchToGlobalMetadataReducer, loggedInUserJwtToken, loggedInUsersAccount.data]);
333
+ prevDefaultCaseGroupIdRef.current = defaultCaseGroupId;
334
+ const currentGroupFilter = ((_a = filterState.filterInfo) === null || _a === void 0 ? void 0 : _a[SolrKeys.group]) || [];
335
+ if (prevGroupFilterRef.current !== undefined &&
336
+ prevGroupFilterRef.current.length > 0 &&
337
+ currentGroupFilter.length === 0) {
338
+ userDismissedDefaultGroupRef.current = true;
339
+ }
340
+ prevGroupFilterRef.current = currentGroupFilter;
341
+ }, [filterState.filterInfo, defaultCaseGroupId]);
180
342
  useEffect(() => {
181
- if (haventLoadedMetadata(allCaseTypes)) {
182
- fetchCaseTypes(dispatchToGlobalMetadataReducer, loggedInUsersAccount.data.secureSupport);
343
+ var _a;
344
+ if (!salesforceAccountId || loggedInUser.isFetching)
345
+ return;
346
+ if (!haventLoadedMetadata(caseGroups, (data) => data === undefined))
347
+ return;
348
+ if ((_a = loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.isInternal) {
349
+ fetchCaseGroupsForAccount(dispatchToGlobalMetadataReducer, apolloClient, salesforceAccountId, defaultCaseGroupId, loggedInContactId, loggedInIsOrgAdmin);
183
350
  }
184
- // when solr is down, we use hydra metadata api to populated filter dropdowns
185
- if (isSolrSearchDown) {
351
+ else {
352
+ fetchCaseGroupsForSSO(dispatchToGlobalMetadataReducer, apolloClient, salesforceAccountId, defaultCaseGroupId, loggedInContactId, loggedInIsOrgAdmin);
353
+ }
354
+ }, [
355
+ apolloClient,
356
+ caseGroups,
357
+ dispatchToGlobalMetadataReducer,
358
+ defaultCaseGroupId,
359
+ loggedInContactId,
360
+ loggedInIsOrgAdmin,
361
+ loggedInUser.isFetching,
362
+ (_f = loggedInUsersAccount.data) === null || _f === void 0 ? void 0 : _f.isInternal,
363
+ salesforceAccountId,
364
+ ]);
365
+ useEffect(() => {
366
+ if (location.pathname !== '/case/list')
367
+ return;
368
+ if (loggedInUser.isFetching || caseGroups.isFetching || caseGroups.data === undefined)
369
+ return;
370
+ if (!shouldApplyDefaultGroupFilter(queryFromUrl, hydraUserPreferences.data))
371
+ return;
372
+ const canAutoSync = isNoFilterApplied(filterState) ||
373
+ isOnlyDefaultFilterApplied(filterState) ||
374
+ isOnlyGroupFilterApplied(filterState.filterInfo);
375
+ if (!canAutoSync)
376
+ return;
377
+ const nextGroupFilter = getDefaultGroupFilterSelection(caseGroups.data, loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.data);
378
+ const currentGroupFilter = filterState.filterInfo[SolrKeys.group] || [];
379
+ if (userDismissedDefaultGroupRef.current && currentGroupFilter.length === 0) {
380
+ return;
381
+ }
382
+ if (isEqual(currentGroupFilter, nextGroupFilter))
383
+ return;
384
+ updateFilterState(filterDispatch, Object.assign(Object.assign({}, filterState), { filterInfo: Object.assign(Object.assign({}, filterState.filterInfo), { [SolrKeys.group]: nextGroupFilter }) }));
385
+ // eslint-disable-next-line react-hooks/exhaustive-deps
386
+ }, [
387
+ defaultCaseGroupId,
388
+ caseGroups.data,
389
+ caseGroups.isFetching,
390
+ loggedInUser.isFetching,
391
+ location.pathname,
392
+ queryFromUrl,
393
+ ]);
394
+ useEffect(() => {
395
+ const loadMetadata = () => __awaiter(this, void 0, void 0, function* () {
396
+ if (haventLoadedMetadata(allCaseTypes)) {
397
+ fetchCaseTypes(dispatchToGlobalMetadataReducer, apolloClient);
398
+ }
186
399
  if (haventLoadedMetadata(allCaseSeverities)) {
187
- fetchCaseSeverities(dispatchToGlobalMetadataReducer, loggedInUsersAccount.data.secureSupport);
400
+ fetchCaseSeverities(dispatchToGlobalMetadataReducer, apolloClient);
188
401
  }
189
402
  if (haventLoadedMetadata(allCaseStatuses)) {
190
- fetchAllStatuses(dispatchToGlobalMetadataReducer, loggedInUsersAccount.data.secureSupport);
403
+ fetchAllStatuses(dispatchToGlobalMetadataReducer, apolloClient);
191
404
  }
192
405
  if (haventLoadedProductsMetadata(allProducts)) {
193
- fetchProducts(dispatchToGlobalMetadataReducer);
406
+ fetchProducts(dispatchToGlobalMetadataReducer, apolloClient);
194
407
  }
195
- // on sfdc fields that only one value is allowed, set filter to first item
196
- const sfdcFilterState = mapValues(filterState.filterInfo, (value, key) => {
197
- //@ts-ignore
198
- if (eligibleSFDCFiltersMultipleValues.includes(key))
199
- return value;
200
- return value[0] ? [value[0]] : [];
201
- });
202
- updateFilterState(filterDispatch, {
203
- //@ts-ignore
204
- filterInfo: Object.assign(Object.assign({}, initialCaseFilterState.filterInfo), sfdcFilterState),
205
- });
206
- }
408
+ });
409
+ loadMetadata();
207
410
  // eslint-disable-next-line react-hooks/exhaustive-deps
208
- }, [
209
- allCaseTypes,
210
- allCaseSeverities,
211
- allCaseStatuses,
212
- allProducts,
213
- dispatchToGlobalMetadataReducer,
214
- loggedInUsersAccount.data.secureSupport,
215
- isSolrSearchDown,
216
- ]);
411
+ }, [allCaseTypes, allCaseSeverities, allCaseStatuses, allProducts, dispatchToGlobalMetadataReducer, apolloClient]);
412
+ function saveFilterQueryInUserPreferences() {
413
+ if (isNoFilterApplied(filterState))
414
+ return;
415
+ const type = filterState.filterQueryInfo.type;
416
+ const recentSearch = {
417
+ filterState: type === CaseSearchQueryType.BASIC ? filterState.filterInfo : {},
418
+ sortState: filterState.sortInfo,
419
+ queryString: type === CaseSearchQueryType.BASIC
420
+ ? filterState.filterQueryInfo.queryString
421
+ : filterState.filterQueryInfo.parsedQuery,
422
+ type,
423
+ };
424
+ try {
425
+ updateUserPreferences(dispatchToGlobalMetadataReducer, loggedInUserRights.data.getSSOUsername(), [{ key: UserPreferencesKeys.mostRecentSearch, value: JSON.stringify(recentSearch) }], 'add');
426
+ }
427
+ catch (e) {
428
+ console.error('Could not save filter query in user preferences');
429
+ }
430
+ }
217
431
  // effect to update url query and call get case api whenever filter state changes
218
432
  useEffect(() => {
219
- var _a, _b, _c;
433
+ var _a, _b, _c, _d;
220
434
  if (!isFirstMount.current) {
221
435
  const urlQuery = (isNoFilterApplied(filterState) || isOnlyDefaultFilterApplied(filterState)) &&
222
436
  !((_a = filterState.filterQueryInfo) === null || _a === void 0 ? void 0 : _a.queryString) &&
223
437
  !filterState.sortInfo.column
224
438
  ? ''
225
439
  : createURLQueryFromFilterState(filterState);
440
+ const paginationKey = `p${(_b = filterState.paginationInfo) === null || _b === void 0 ? void 0 : _b.currentPage}_s${(_c = filterState.paginationInfo) === null || _c === void 0 ? void 0 : _c.pageSize}`;
441
+ const advanceSearchKey = [
442
+ ((_d = filterState.filterQueryInfo) === null || _d === void 0 ? void 0 : _d.parsedQuery) || '',
443
+ JSON.stringify(filterState.advanceSearchDateRanges || null),
444
+ ].join('|');
445
+ const fullQueryKey = `${urlQuery}_${paginationKey}_${advanceSearchKey}`;
446
+ if (fullQueryKey === lastPushedQueryRef.current) {
447
+ return;
448
+ }
449
+ if (urlQuery !== lastPushedQueryRef.current) {
450
+ clearPageCursors();
451
+ }
226
452
  setCurrentQuery(CaseListDispatch, urlQuery);
453
+ lastPushedQueryRef.current = urlQuery;
227
454
  searchParams[FILTER_URL_QUERY_SEARCH_PARAM] = encodeURIComponent(urlQuery);
228
- searchParams[FILTER_URL_CURRENT_PAGE_SEARCH_PARAM] = (_b = filterState.paginationInfo) === null || _b === void 0 ? void 0 : _b.currentPage.toString();
229
- searchParams[FILTER_URL_PAGE_SIZE_SEARCH_PARAM] = (_c = filterState.paginationInfo) === null || _c === void 0 ? void 0 : _c.pageSize.toString();
230
455
  searchParams[FILTER_URL_QUERY_TYPE] = filterState.filterQueryInfo.type;
456
+ delete searchParams[FILTER_URL_CURRENT_PAGE_SEARCH_PARAM];
457
+ delete searchParams[FILTER_URL_PAGE_SIZE_SEARCH_PARAM];
231
458
  props.routeProps.history.push({
232
459
  search: getStringifiedParams(searchParams),
233
460
  });
234
461
  saveFilterQueryInUserPreferences();
235
- // so that we don't call get cases every time user switches between basic and advanced without any filters applied
236
- if (isSearchTypeChanged &&
237
- !filterState.filterQueryInfo.queryString &&
238
- isNoFilterApplied(filterState) &&
239
- filterValuesFromFacetResponse // if this is null, it means it is the first page load so get cases anyway
240
- )
241
- return;
242
462
  getCases(filterState);
243
463
  }
244
464
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -248,17 +468,46 @@ export function CaseList(props) {
248
468
  if (bookmarkedAccounts.isFetching ||
249
469
  managedAccounts.isFetching ||
250
470
  caseGroups.isFetching ||
251
- caseGroups.data === undefined)
471
+ caseGroups.data === undefined ||
472
+ caseRecordTypes.isFetching ||
473
+ isEmpty(caseRecordTypes.data))
252
474
  return;
475
+ const decodedQueryFromUrl = (() => {
476
+ if (!queryFromUrl || queryFromUrl === 'undefined') {
477
+ return '';
478
+ }
479
+ try {
480
+ return decodeURIComponent(queryFromUrl);
481
+ }
482
+ catch (_a) {
483
+ return queryFromUrl;
484
+ }
485
+ })();
253
486
  // when user manually changes url and hit enter, new result is fetched without refreshing the page
254
487
  if (!isFirstMount.current) {
255
- if (queryFromUrl !== currentQuery) {
256
- const filterStateFromQueryUrl = createFilterStateFromUrlQuery(queryFromUrl, globalMetadataState, pageSizeFromUrl, currentPageFromUrl, searchType);
488
+ if (decodedQueryFromUrl &&
489
+ decodedQueryFromUrl !== currentQuery &&
490
+ decodedQueryFromUrl !== lastPushedQueryRef.current) {
491
+ const filterStateFromQueryUrl = createFilterStateFromUrlQuery(decodedQueryFromUrl, globalMetadataState, undefined, 1, searchType);
257
492
  updateFilterState(filterDispatch, filterStateFromQueryUrl);
258
493
  }
259
494
  return;
260
495
  }
261
496
  if (isFirstMount.current) {
497
+ if (searchParams.rhcd) {
498
+ // this is to check if rhcd is passed on first load
499
+ setRHCDValue(searchParams.rhcd);
500
+ }
501
+ const hasExplicitUrlQuery = Boolean(decodedQueryFromUrl.trim());
502
+ if (hasExplicitUrlQuery && decodedQueryFromUrl !== currentQuery) {
503
+ const { initFilterState, defaultSearchName } = useFilterStateInit.set(decodedQueryFromUrl, undefined, 1, searchType);
504
+ setDefaultSavedSearchName(defaultSearchName);
505
+ setCurrentQuery(CaseListDispatch, decodedQueryFromUrl);
506
+ lastPushedQueryRef.current = decodedQueryFromUrl;
507
+ isFirstMount.current = false;
508
+ updateFilterState(filterDispatch, initFilterState);
509
+ return;
510
+ }
262
511
  // user came to page from another tab - second time on page as currentQuery is set
263
512
  // - keep state and show the result that we already have in state
264
513
  // - update url to reflect filter state
@@ -266,8 +515,6 @@ export function CaseList(props) {
266
515
  if (currentQuery) {
267
516
  const navObj = {
268
517
  [FILTER_URL_QUERY_SEARCH_PARAM]: encodeURIComponent(currentQuery),
269
- [FILTER_URL_PAGE_SIZE_SEARCH_PARAM]: filterState.paginationInfo.pageSize,
270
- [FILTER_URL_CURRENT_PAGE_SEARCH_PARAM]: filterState.paginationInfo.currentPage,
271
518
  [FILTER_URL_QUERY_TYPE]: filterState.filterQueryInfo.type,
272
519
  };
273
520
  props.routeProps.history.replace({ search: getStringifiedParams(navObj) });
@@ -275,35 +522,31 @@ export function CaseList(props) {
275
522
  isFirstMount.current = false;
276
523
  return;
277
524
  }
278
- /*** user comes to this point on first time app load landing on case list ***/
279
- if (searchParams.rhcd) {
280
- // this is to check if rhcd is passed on first load
281
- setRHCDValue(searchParams.rhcd);
282
- }
283
525
  // set filter state based on url or default saved search
284
- const { initFilterState, defaultSearchName } = useFilterStateInit.set(decodeURIComponent(queryFromUrl), pageSizeFromUrl, currentPageFromUrl, searchType);
526
+ // Remove when we get OFFSET field from SCT
527
+ // Always reset to page 1 on fresh load — cursor-based pagination
528
+ // has no stored cursors after refresh, so page > 1 would cause a mismatch
529
+ const { initFilterState, defaultSearchName } = useFilterStateInit.set(decodedQueryFromUrl, undefined, 1, searchType);
285
530
  // to set default saved search name
286
531
  setDefaultSavedSearchName(defaultSearchName);
287
532
  // set default params when they are empty
288
- if (!queryFromUrl) {
533
+ if (!decodedQueryFromUrl) {
289
534
  searchParams[FILTER_URL_QUERY_SEARCH_PARAM] = ' orderBy lastModifiedDate desc';
290
535
  }
291
- setCurrentQuery(CaseListDispatch, queryFromUrl);
536
+ setCurrentQuery(CaseListDispatch, decodedQueryFromUrl);
292
537
  isFirstMount.current = false;
293
538
  // we only update the state without api call as we fetch result in another useEffect that observes the state
294
539
  updateFilterState(filterDispatch, initFilterState);
295
540
  }
296
541
  // eslint-disable-next-line react-hooks/exhaustive-deps
297
- }, [managedAccounts, bookmarkedAccounts, caseGroups, queryFromUrl, pageSizeFromUrl, currentPageFromUrl]);
298
- // effect to initially set the filter state to expanded and when we switch from advanced to basic mode
542
+ }, [managedAccounts, bookmarkedAccounts, caseGroups, caseRecordTypes, queryFromUrl]);
543
+ // effect to initially set the filter state to expanded on load
299
544
  useEffect(() => {
300
- // currently there is no easy way to set the panel as expanded on initial load
301
- // also we only use the standalone panel and manually change the panel state on toggle btn click
302
- isCaseListFilterPanelExanded && isXLScreen && isBasicSearchMode && toggleFilterSection(true);
545
+ isCaseListFilterPanelExanded && isXLScreen && toggleFilterSection(true);
303
546
  // eslint-disable-next-line react-hooks/exhaustive-deps
304
- }, [isBasicSearchMode]);
547
+ }, []);
305
548
  const onConfirmTraditionalSupportAgreement = () => {
306
- updateCaseListTraditionalSupportAgreed(globalDispatchContext, true);
549
+ setTraditionalSupportSessionAgreed(globalDispatchContext, true);
307
550
  };
308
551
  const displayRHCDAlert = () => {
309
552
  const openClosedCopy = `Only showing cases that were ${RHCDValue} during the selected time range specified in
@@ -327,12 +570,6 @@ export function CaseList(props) {
327
570
  return (React.createElement(React.Fragment, null,
328
571
  React.createElement(CSSUserModal, { onConfirmTraditionalSupportAgreement: onConfirmTraditionalSupportAgreement, display: !caseListTraditionalSupportAgreed }),
329
572
  React.createElement("article", { id: "rh-support-cases", className: "cases-main" },
330
- isSolrSearchDown && (React.createElement(Alert, { isInline: true, variant: AlertVariant.warning, component: "p", title: React.createElement(Trans, null,
331
- "Case search is working with limited functionality. Please check",
332
- ' ',
333
- React.createElement("a", { href: "https://status.redhat.com", target: "_blank", rel: "noreferrer", "data-tracking-id": "caselist-redirect-status-page" }, "status page"),
334
- ' ',
335
- "for details.") })),
336
573
  React.createElement("section", { className: "case-search-top" },
337
574
  !isEmpty(RHCDValue) && isRHCDAlertShown && React.createElement("div", { className: "push-bottom" }, displayRHCDAlert()),
338
575
  React.createElement("div", { className: "search-wrapper" },
@@ -340,17 +577,17 @@ export function CaseList(props) {
340
577
  React.createElement(NewCaseButton, { routeProps: props.routeProps })),
341
578
  React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading case search input') } },
342
579
  React.createElement(CaseSearch, { defaultSavedSearchName: defaultSavedSearchName }))),
343
- isBasicSearchMode && (React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filter chips') } },
344
- React.createElement(CaseListFilterChips, { productVersionPivotValues: get(pivotValues, SolrPivotKeys.product_version, []), isSolrSearchDown: isSolrSearchDown })))),
580
+ React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filter chips') } },
581
+ React.createElement(CaseListFilterChips, null))),
345
582
  React.createElement("section", { className: "case-search-bottom" },
346
- isBasicSearchMode && (React.createElement("aside", { className: `case-search-filters ${((_a = filterSectionRef.current) === null || _a === void 0 ? void 0 : _a.expanded) ? '' : 'collapsed'}` },
347
- React.createElement("h2", { className: "filter-header pf-v6-u-display-flex" }, ((_b = filterSectionRef.current) === null || _b === void 0 ? void 0 : _b.expanded) ? (React.createElement(React.Fragment, null,
583
+ React.createElement("aside", { className: `case-search-filters ${((_g = filterSectionRef.current) === null || _g === void 0 ? void 0 : _g.expanded) ? '' : 'collapsed'}` },
584
+ React.createElement("h2", { className: "filter-header pf-v6-u-display-flex" }, ((_h = filterSectionRef.current) === null || _h === void 0 ? void 0 : _h.expanded) ? (React.createElement(React.Fragment, null,
348
585
  React.createElement(Button, { isInline: true, className: "pf-v6-u-flex-shrink-0 pf-v6-u-flex-none case-search-filter-text-button", variant: "link", title: t('Collapse filter section'), "data-tracking-id": "collapse-case-list-filter", onClick: onToggleFilterBtnClick, iconPosition: "right", icon: React.createElement(OpenDrawerRightIcon, { className: "mirrored" }) },
349
586
  React.createElement(Trans, null, "Filters")))) : (React.createElement(Button, { isInline: true, className: "pf-v6-c-button pf-m-link pf-m-inline pf-v6-u-flex-shrink-0 pf-v6-u-flex-none pf-v6-u-display-flex pf-v6-u-align-items-center pf-v6-u-justify-content-center pf-v6-u-px-lg", variant: "link", title: t('Expand filter section'), "data-tracking-id": "expand-case-list-filter", onClick: onToggleFilterBtnClick, iconPosition: "right", icon: React.createElement(OpenDrawerRightIcon, null) }, isXLScreen ? null : React.createElement(Trans, null, "Filters")))),
350
587
  React.createElement("div", { className: "filter-wrapper" },
351
588
  React.createElement("pfe-collapse-panel", { id: "case-filters-panel", "pfe-animation": "false", ref: filterSectionRef },
352
589
  React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading filters') } },
353
- React.createElement(CaseListFilters, { filterValues: filterValuesFromFacetResponse, allCaseTypes: allCaseTypes, allCaseStatuses: allCaseStatuses, allCaseSeverities: allCaseSeverities, allProducts: allProducts, isSolrSearchDown: isSolrSearchDown })))))),
590
+ React.createElement(CaseListFilters, { allCaseTypes: allCaseTypes, allCaseStatuses: allCaseStatuses, allCaseSeverities: allCaseSeverities, allProducts: allProducts }))))),
354
591
  React.createElement("section", { className: "case-search-table pf-v6-u-display-flex pf-v6-u-flex-direction-column" },
355
- React.createElement(CaseListTable, { caseList: caseList, caseGroups: caseGroups.data || [], loggedInUserRights: loggedInUserRights.data, sortInfo: filterState.sortInfo, paginationInfo: filterState.paginationInfo, isCaseListPageLoading: isFetching, hasError: hasError, isSolrDown: isSolrSearchDown }))))));
592
+ React.createElement(CaseListTable, { caseList: caseList, caseGroups: caseGroups.data || [], loggedInUserRights: loggedInUserRights.data, sortInfo: filterState.sortInfo, isCaseListPageLoading: isFetching, hasError: hasError, hasNextPage: hasNextPage, isLoadingMore: isLoadingMore, loadMoreError: loadMoreError, loadMoreRetryCount: loadMoreRetryCount, onRetryLoadMore: retryLoadMore, onRetryFetch: retryCaseListFetch, caseLabelsFetchError: caseLabelsFetchError, onCasesCloseSuccess: () => getCases(filterState), sentinelRef: sentinelRef }))))));
356
593
  }