@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.
- package/lib/esm/components/case/NewCaseButton.js +1 -1
- package/lib/esm/components/case-list/CaseList.d.ts +0 -7
- package/lib/esm/components/case-list/CaseList.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseList.js +372 -137
- package/lib/esm/components/case-list/CaseListContext.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseListContext.js +5 -2
- package/lib/esm/components/case-list/CaseListFilterContext.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseListFilterContext.js +2 -1
- package/lib/esm/components/case-list/CaseListFilterHelpers.d.ts +3 -2
- package/lib/esm/components/case-list/CaseListFilterHelpers.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseListFilterHelpers.js +19 -6
- package/lib/esm/components/case-list/CaseListFilterReducer.d.ts +36 -4
- package/lib/esm/components/case-list/CaseListFilterReducer.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseListFilterReducer.js +6 -12
- package/lib/esm/components/case-list/CaseListReducer.d.ts +22 -10
- package/lib/esm/components/case-list/CaseListReducer.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseListReducer.js +25 -7
- package/lib/esm/components/case-list/case-list-filters/AccountsFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/AccountsFilter.js +18 -11
- package/lib/esm/components/case-list/case-list-filters/AdditionalFilters.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/AdditionalFilters.js +20 -4
- package/lib/esm/components/case-list/case-list-filters/CaseLabelsFilter.d.ts +3 -0
- package/lib/esm/components/case-list/case-list-filters/CaseLabelsFilter.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-list-filters/CaseLabelsFilter.js +178 -0
- package/lib/esm/components/case-list/case-list-filters/CaseListFilterChips.d.ts +1 -7
- package/lib/esm/components/case-list/case-list-filters/CaseListFilterChips.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/CaseListFilterChips.js +12 -16
- package/lib/esm/components/case-list/case-list-filters/CaseListFilters.d.ts +2 -5
- package/lib/esm/components/case-list/case-list-filters/CaseListFilters.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/CaseListFilters.js +14 -13
- package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilter.js +21 -14
- package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilterChip.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/CreatorSsoNameFilterChip.js +3 -0
- package/lib/esm/components/case-list/case-list-filters/GroupsFilter.d.ts +11 -1
- package/lib/esm/components/case-list/case-list-filters/GroupsFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/GroupsFilter.js +90 -70
- package/lib/esm/components/case-list/case-list-filters/ProductFilterChip.d.ts +1 -3
- package/lib/esm/components/case-list/case-list-filters/ProductFilterChip.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/ProductFilterChip.js +2 -2
- package/lib/esm/components/case-list/case-list-filters/ProductsFilter.d.ts +5 -4
- package/lib/esm/components/case-list/case-list-filters/ProductsFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/ProductsFilter.js +15 -54
- package/lib/esm/components/case-list/case-list-filters/SeverityFilter.d.ts +0 -3
- package/lib/esm/components/case-list/case-list-filters/SeverityFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/SeverityFilter.js +18 -44
- package/lib/esm/components/case-list/case-list-filters/StatusFilter.d.ts +0 -3
- package/lib/esm/components/case-list/case-list-filters/StatusFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/StatusFilter.js +23 -49
- package/lib/esm/components/case-list/case-list-filters/VersionsFilter.d.ts +1 -3
- package/lib/esm/components/case-list/case-list-filters/VersionsFilter.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-filters/VersionsFilter.js +60 -59
- package/lib/esm/components/case-list/case-list-table/ArchivedCaseLabel.d.ts +3 -0
- package/lib/esm/components/case-list/case-list-table/ArchivedCaseLabel.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-list-table/ArchivedCaseLabel.js +8 -0
- package/lib/esm/components/case-list/case-list-table/CaseListLabelGroup.d.ts +9 -0
- package/lib/esm/components/case-list/case-list-table/CaseListLabelGroup.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-list-table/CaseListLabelGroup.js +105 -0
- package/lib/esm/components/case-list/case-list-table/CaseListTable.d.ts +10 -3
- package/lib/esm/components/case-list/case-list-table/CaseListTable.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-table/CaseListTable.js +98 -84
- package/lib/esm/components/case-list/case-list-table/CaseListTableRow.d.ts +33 -0
- package/lib/esm/components/case-list/case-list-table/CaseListTableRow.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-list-table/CaseListTableRow.js +51 -0
- package/lib/esm/components/case-list/case-list-table/CaseListTableSkeletonRow.d.ts +9 -0
- package/lib/esm/components/case-list/case-list-table/CaseListTableSkeletonRow.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-list-table/CaseListTableSkeletonRow.js +10 -0
- package/lib/esm/components/case-list/case-list-table/CloseCaseBtn.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-table/CloseCaseBtn.js +27 -28
- package/lib/esm/components/case-list/case-list-table/DownloadCSVFileModal.d.ts +0 -5
- package/lib/esm/components/case-list/case-list-table/DownloadCSVFileModal.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-table/DownloadCSVFileModal.js +51 -70
- package/lib/esm/components/case-list/case-list-table/ExportCaseListCSV.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-table/ExportCaseListCSV.js +5 -15
- package/lib/esm/components/case-list/case-list-table/SeverityLabel.js +1 -1
- package/lib/esm/components/case-list/case-list-table/TableActionsDropdown.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-table/TableActionsDropdown.js +4 -5
- package/lib/esm/components/case-list/case-list-table/table-column-selector/TableColumnSelector.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-list-table/table-column-selector/TableColumnSelector.js +1 -0
- package/lib/esm/components/case-list/case-search/AdvanceSearchToggleButton.d.ts +8 -0
- package/lib/esm/components/case-list/case-search/AdvanceSearchToggleButton.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/AdvanceSearchToggleButton.js +8 -0
- package/lib/esm/components/case-list/case-search/BookmarkedSearchesSelector.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-search/BookmarkedSearchesSelector.js +15 -2
- package/lib/esm/components/case-list/case-search/CaseSearch.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-search/CaseSearch.js +55 -24
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAccountSection.d.ts +10 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAccountSection.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAccountSection.js +29 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAuditsSection.d.ts +10 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAuditsSection.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchAuditsSection.js +16 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchCaseSection.d.ts +9 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchCaseSection.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchCaseSection.js +21 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchDateRangeField.d.ts +12 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchDateRangeField.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchDateRangeField.js +31 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchFieldBlock.d.ts +10 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchFieldBlock.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchFieldBlock.js +10 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchModal.d.ts +10 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchModal.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchModal.js +92 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchOwnerSection.d.ts +9 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchOwnerSection.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchOwnerSection.js +20 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchProductSection.d.ts +9 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchProductSection.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/AdvanceSearchProductSection.js +28 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/ProductVersionDrilldownSelect.d.ts +9 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/ProductVersionDrilldownSelect.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/ProductVersionDrilldownSelect.js +241 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/SelectableLabelFilter.d.ts +11 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/SelectableLabelFilter.d.ts.map +1 -0
- package/lib/esm/components/case-list/case-search/advance-search-modal/SelectableLabelFilter.js +23 -0
- package/lib/esm/components/case-list/case-search/useAdvanceSearchParser.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-search/useAdvanceSearchParser.js +2 -1
- package/lib/esm/css/caseList.css +197 -28
- package/lib/esm/css/caseSearch.css +114 -0
- package/lib/esm/enums/case.d.ts +13 -5
- package/lib/esm/enums/case.d.ts.map +1 -1
- package/lib/esm/enums/case.js +23 -3
- package/lib/esm/enums/caseSearch.d.ts +3 -0
- package/lib/esm/enums/caseSearch.d.ts.map +1 -1
- package/lib/esm/enums/caseSearch.js +2 -1
- package/lib/esm/enums/filters.d.ts +5 -1
- package/lib/esm/enums/filters.d.ts.map +1 -1
- package/lib/esm/enums/filters.js +4 -0
- package/lib/esm/hooks/useCaseLabels.d.ts +14 -0
- package/lib/esm/hooks/useCaseLabels.d.ts.map +1 -0
- package/lib/esm/hooks/useCaseLabels.js +50 -0
- package/lib/esm/hooks/useCloseCase.d.ts +1 -1
- package/lib/esm/hooks/useCloseCase.d.ts.map +1 -1
- package/lib/esm/hooks/useCloseCase.js +54 -30
- package/lib/esm/hooks/useExportCaseListCSV.d.ts.map +1 -1
- package/lib/esm/hooks/useExportCaseListCSV.js +1 -9
- package/lib/esm/hooks/useFilterStateOnLoad.d.ts +1 -1
- package/lib/esm/hooks/useFilterStateOnLoad.d.ts.map +1 -1
- package/lib/esm/hooks/useFilterStateOnLoad.js +7 -5
- package/lib/esm/index.js +1 -0
- package/lib/esm/models/caseList.d.ts +1 -0
- package/lib/esm/models/caseList.d.ts.map +1 -1
- package/lib/esm/test-utils/mockData.d.ts +1 -0
- package/lib/esm/test-utils/mockData.d.ts.map +1 -1
- package/lib/esm/test-utils/mockData.js +2 -1
- package/lib/esm/utils/advanceSearchFormMapper.d.ts +11 -0
- package/lib/esm/utils/advanceSearchFormMapper.d.ts.map +1 -0
- package/lib/esm/utils/advanceSearchFormMapper.js +71 -0
- package/lib/esm/utils/advanceSearchUtils.d.ts +24 -0
- package/lib/esm/utils/advanceSearchUtils.d.ts.map +1 -0
- package/lib/esm/utils/advanceSearchUtils.js +150 -0
- package/lib/esm/utils/caseGroupDefaultFilterUtils.d.ts +12 -0
- package/lib/esm/utils/caseGroupDefaultFilterUtils.d.ts.map +1 -0
- package/lib/esm/utils/caseGroupDefaultFilterUtils.js +34 -0
- package/lib/esm/utils/caseGroupDefaultUtils.d.ts +10 -0
- package/lib/esm/utils/caseGroupDefaultUtils.d.ts.map +1 -0
- package/lib/esm/utils/caseGroupDefaultUtils.js +20 -0
- package/lib/esm/utils/caseListGraphQLUtils.d.ts +28 -0
- package/lib/esm/utils/caseListGraphQLUtils.d.ts.map +1 -0
- package/lib/esm/utils/caseListGraphQLUtils.js +304 -0
- package/lib/esm/utils/caseListMapper.d.ts +6 -0
- package/lib/esm/utils/caseListMapper.d.ts.map +1 -0
- package/lib/esm/utils/caseListMapper.js +47 -0
- package/lib/esm/utils/caseListVariablesBuilder.d.ts +17 -0
- package/lib/esm/utils/caseListVariablesBuilder.d.ts.map +1 -0
- package/lib/esm/utils/caseListVariablesBuilder.js +535 -0
- package/lib/esm/utils/caseSearchUtils.d.ts.map +1 -1
- package/lib/esm/utils/caseSearchUtils.js +39 -2
- package/lib/esm/utils/constants.d.ts +4 -1
- package/lib/esm/utils/constants.d.ts.map +1 -1
- package/lib/esm/utils/constants.js +9 -2
- package/lib/esm/utils/mockSolrResponse.js +1 -1
- 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,
|
|
15
|
-
import { CSSUserModal, fetchAllStatuses, fetchCaseGroupsForAccount, fetchCaseGroupsForSSO, fetchCaseSeverities, fetchCaseTypes, fetchProducts, GlobalMetadataDispatchContext, GlobalMetadataStateContext,
|
|
16
|
-
import { getStringifiedParams, getUrlParsedParams, haventLoadedMetadata, haventLoadedProductsMetadata,
|
|
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
|
|
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 {
|
|
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 {
|
|
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
|
|
37
|
-
import {
|
|
39
|
+
import { CaseListFilterDispatchContext, CaseListFilterStateContext } from './CaseListFilterContext';
|
|
40
|
+
import { isNoFilterApplied, isOnlyDefaultFilterApplied, isOnlyGroupFilterApplied } from './CaseListFilterHelpers';
|
|
38
41
|
import { updateFilterState } from './CaseListFilterReducer';
|
|
39
|
-
import { setCaseList, setCurrentQuery,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
171
|
+
var _a;
|
|
77
172
|
try {
|
|
78
|
-
|
|
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
|
-
|
|
85
|
-
let controller = new AbortController();
|
|
176
|
+
const controller = new AbortController();
|
|
86
177
|
abortControllerRef.current = controller;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
97
|
-
|
|
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
|
|
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 (
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
182
|
-
|
|
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
|
-
|
|
185
|
-
|
|
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,
|
|
398
|
+
fetchCaseSeverities(dispatchToGlobalMetadataReducer, apolloClient);
|
|
188
399
|
}
|
|
189
400
|
if (haventLoadedMetadata(allCaseStatuses)) {
|
|
190
|
-
fetchAllStatuses(dispatchToGlobalMetadataReducer,
|
|
401
|
+
fetchAllStatuses(dispatchToGlobalMetadataReducer, apolloClient);
|
|
191
402
|
}
|
|
192
403
|
if (haventLoadedProductsMetadata(allProducts)) {
|
|
193
|
-
fetchProducts(dispatchToGlobalMetadataReducer);
|
|
404
|
+
fetchProducts(dispatchToGlobalMetadataReducer, apolloClient);
|
|
194
405
|
}
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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 (
|
|
256
|
-
|
|
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
|
-
|
|
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 (!
|
|
531
|
+
if (!decodedQueryFromUrl) {
|
|
289
532
|
searchParams[FILTER_URL_QUERY_SEARCH_PARAM] = ' orderBy lastModifiedDate desc';
|
|
290
533
|
}
|
|
291
|
-
setCurrentQuery(CaseListDispatch,
|
|
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,
|
|
298
|
-
// effect to initially set the filter state to expanded
|
|
540
|
+
}, [managedAccounts, bookmarkedAccounts, caseGroups, caseRecordTypes, queryFromUrl]);
|
|
541
|
+
// effect to initially set the filter state to expanded on load
|
|
299
542
|
useEffect(() => {
|
|
300
|
-
|
|
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
|
-
}, [
|
|
545
|
+
}, []);
|
|
305
546
|
const onConfirmTraditionalSupportAgreement = () => {
|
|
306
|
-
|
|
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
|
-
|
|
344
|
-
React.createElement(CaseListFilterChips,
|
|
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
|
-
|
|
347
|
-
React.createElement("h2", { className: "filter-header pf-v6-u-display-flex" }, ((
|
|
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, {
|
|
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,
|
|
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
|
}
|