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