@rh-support/cases 2.6.235 → 2.7.10

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