@rh-support/cases 0.2.38 → 0.2.41
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-list/CaseList.d.ts.map +1 -1
- package/lib/esm/components/case-list/CaseList.js +3 -4
- package/lib/esm/components/case-list/case-search/BookmarkedSearchesSelector.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-search/BookmarkedSearchesSelector.js +12 -10
- package/lib/esm/components/case-list/case-search/CaseSearch.js +3 -3
- package/lib/esm/components/case-list/case-search/SaveCaseSearchModal.d.ts.map +1 -1
- package/lib/esm/components/case-list/case-search/SaveCaseSearchModal.js +48 -35
- package/lib/esm/css/caseList.css +2 -2
- package/lib/esm/enums/caseSearch.d.ts +2 -1
- package/lib/esm/enums/caseSearch.d.ts.map +1 -1
- package/lib/esm/enums/caseSearch.js +2 -2
- 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 +9 -14
- package/lib/esm/utils/caseSearchUtils.js +4 -4
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseList.d.ts","sourceRoot":"","sources":["../../../../src/components/case-list/CaseList.tsx"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAChC,OAAO,0BAA0B,CAAC;AA4BlC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAKH,0BAA0B,EAI7B,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,mBAAmB,EAAe,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAM1C,OAAO,EAAgB,WAAW,EAA2B,MAAM,uBAAuB,CAAC;AA2B3F,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC3D,YAAY,EAAE,cAAc,EAAE,CAAC;CAClC;AAED,oBAAY,YAAY,GAAG,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAM5F,MAAM,WAAW,gBAAgB;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"CaseList.d.ts","sourceRoot":"","sources":["../../../../src/components/case-list/CaseList.tsx"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAChC,OAAO,0BAA0B,CAAC;AA4BlC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAKH,0BAA0B,EAI7B,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,mBAAmB,EAAe,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAM1C,OAAO,EAAgB,WAAW,EAA2B,MAAM,uBAAuB,CAAC;AA2B3F,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC3D,YAAY,EAAE,cAAc,EAAE,CAAC;CAClC;AAED,oBAAY,YAAY,GAAG,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAM5F,MAAM,WAAW,gBAAgB;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,eA4brC"}
|
|
@@ -258,16 +258,15 @@ export function CaseList(props) {
|
|
|
258
258
|
// move saved user data in localstorage to user preferences db - needs to be removed after a while
|
|
259
259
|
useMoveCache.save();
|
|
260
260
|
// set filter state based on url or default saved search
|
|
261
|
-
useFilterStateInit.set(queryFromUrl, pageSizeFromUrl, currentPageFromUrl, searchType);
|
|
261
|
+
const initFilterState = useFilterStateInit.set(queryFromUrl, pageSizeFromUrl, currentPageFromUrl, searchType);
|
|
262
262
|
// set default params when they are empty
|
|
263
263
|
if (!queryFromUrl) {
|
|
264
264
|
searchParams[FILTER_URL_QUERY_SEARCH_PARAM] = ' orderBy lastModifiedDate desc';
|
|
265
265
|
}
|
|
266
|
-
props.routeProps.history.replace({
|
|
267
|
-
search: getStringifiedParams(searchParams),
|
|
268
|
-
});
|
|
269
266
|
setCurrentQuery(CaseListDispatch, queryFromUrl);
|
|
270
267
|
isFirstMount.current = false;
|
|
268
|
+
// we only update the state without api call as we fetch result in another useEffect that observes the state
|
|
269
|
+
updateFilterState(filterDispatch, initFilterState);
|
|
271
270
|
}
|
|
272
271
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
273
272
|
}, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BookmarkedSearchesSelector.d.ts","sourceRoot":"","sources":["../../../../../src/components/case-list/case-search/BookmarkedSearchesSelector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BookmarkedSearchesSelector.d.ts","sourceRoot":"","sources":["../../../../../src/components/case-list/case-search/BookmarkedSearchesSelector.tsx"],"names":[],"mappings":"AAwBA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAWhE,UAAU,MAAM;IACZ,uBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,mBAAmB,CAAC;CAC1C;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,eA6MvD"}
|
|
@@ -3,13 +3,14 @@ import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon
|
|
|
3
3
|
import StarIcon from '@patternfly/react-icons/dist/js/icons/star-icon';
|
|
4
4
|
import { ConfirmationServiceProvider } from '@rh-support/components';
|
|
5
5
|
import { GlobalMetadataStateContext, UserPreferencesKeys } from '@rh-support/react-context';
|
|
6
|
+
import filter from 'lodash/filter';
|
|
6
7
|
import find from 'lodash/find';
|
|
7
8
|
import flatMap from 'lodash/flatMap';
|
|
8
9
|
import isEmpty from 'lodash/isEmpty';
|
|
9
10
|
import isEqual from 'lodash/isEqual';
|
|
10
11
|
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
11
12
|
import { Trans, useTranslation } from 'react-i18next';
|
|
12
|
-
import { CaseListFilterDispatchContext, CaseListFilterStateContext } from '../CaseListFilterContext';
|
|
13
|
+
import { CaseListFilterDispatchContext, CaseListFilterStateContext, initialCaseFilterState, } from '../CaseListFilterContext';
|
|
13
14
|
import { isNoFilterApplied, isOnlyDefaultFilterApplied } from '../CaseListFilterHelpers';
|
|
14
15
|
import { clearFilters, updateFilterQuery, updateFilterState, updateSort } from '../CaseListFilterReducer';
|
|
15
16
|
import { SaveCaseSearchModal } from './SaveCaseSearchModal';
|
|
@@ -21,7 +22,7 @@ export function BookmarkedSearchesSelector(props) {
|
|
|
21
22
|
const [mostRecentSearch, setMostRecentSearch] = useState({});
|
|
22
23
|
const [selectedSearch, setSelectedSearch] = useState('');
|
|
23
24
|
const filterState = useContext(CaseListFilterStateContext);
|
|
24
|
-
const { filterQueryInfo, filterInfo
|
|
25
|
+
const { filterQueryInfo, filterInfo } = filterState;
|
|
25
26
|
const [isSaveSearchModalOpen, setIsSaveSearchModalOpen] = useState(false);
|
|
26
27
|
const [isMenuOpen, toggleMenu] = useState(false);
|
|
27
28
|
const isUpdatingFilters = useRef(false);
|
|
@@ -46,16 +47,17 @@ export function BookmarkedSearchesSelector(props) {
|
|
|
46
47
|
}, [props.currentCaseSearchString]);
|
|
47
48
|
useEffect(() => {
|
|
48
49
|
if (selectedSearch && bookmarkedSearches[selectedSearch] && !isUpdatingFilters.current) {
|
|
49
|
-
const { filterState:
|
|
50
|
+
const { filterState: savedSearchFilterInfo, type: savedSearchType } = bookmarkedSearches[selectedSearch];
|
|
50
51
|
// if selected bookmark search is equal to the current filter state
|
|
51
|
-
const isFilterStatesEqual = isEqual(
|
|
52
|
-
// if
|
|
53
|
-
|
|
52
|
+
const isFilterStatesEqual = isEqual(filter(savedSearchFilterInfo, (i) => i.length !== 0), filter(filterInfo, (i) => i.length !== 0));
|
|
53
|
+
// if selected saved search and current selected filters are not equal, we need to enable saved
|
|
54
|
+
// search button and we need to give user ability to bookmark another search
|
|
55
|
+
if (!isFilterStatesEqual || savedSearchType !== filterQueryInfo.type) {
|
|
54
56
|
setSelectedSearch('');
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
|
-
}, [filterInfo, filterQueryInfo
|
|
60
|
+
}, [filterInfo, filterQueryInfo]);
|
|
59
61
|
const onMenuToggle = () => {
|
|
60
62
|
toggleMenu(!isMenuOpen);
|
|
61
63
|
};
|
|
@@ -67,7 +69,7 @@ export function BookmarkedSearchesSelector(props) {
|
|
|
67
69
|
const { filterState: filterStateSaved, queryString, type, sortState } = searchQuery;
|
|
68
70
|
// update filters with new value
|
|
69
71
|
queryString && updateFilterQuery(dispatch, { queryString, type });
|
|
70
|
-
|
|
72
|
+
updateFilterState(dispatch, { filterInfo: Object.assign(Object.assign({}, initialCaseFilterState.filterInfo), filterStateSaved) });
|
|
71
73
|
sortState && updateSort(dispatch, sortState);
|
|
72
74
|
doToggle && toggleMenu(!isMenuOpen);
|
|
73
75
|
isUpdatingFilters.current = false;
|
|
@@ -77,6 +79,7 @@ export function BookmarkedSearchesSelector(props) {
|
|
|
77
79
|
toggleMenu(false);
|
|
78
80
|
};
|
|
79
81
|
const onEditSavedSearchClick = (searchName) => (e) => {
|
|
82
|
+
e.preventDefault();
|
|
80
83
|
e.stopPropagation();
|
|
81
84
|
setSelectedSearchNameToEdit(searchName);
|
|
82
85
|
setIsAddingBookmarkSearch(false);
|
|
@@ -120,6 +123,5 @@ export function BookmarkedSearchesSelector(props) {
|
|
|
120
123
|
], splitButtonVariant: "action", onToggle: onMenuToggle, "aria-label": t(`${isMenuOpen ? 'Close' : 'Open'} bookmarked searches selector'`), isDisabled: !bookmarkedSearches }), disabled: hydraUserPreferences.isFetching || hydraUserPreferences.isError }),
|
|
121
124
|
flatMap(filterInfo).length === 0 && (React.createElement(Button, { variant: "link", onClick: onBookmarkSelectorChange('', mostRecentSearch, false), "data-tracking-id": "case-most-recent-search-button", className: "most-recent-search-button" },
|
|
122
125
|
React.createElement(Trans, null, "Restore most recent filters")))),
|
|
123
|
-
React.createElement(ConfirmationServiceProvider, null,
|
|
124
|
-
React.createElement(SaveCaseSearchModal, { isModalOpen: isSaveSearchModalOpen, modalToggle: modalToggle, isAdding: isAddingBookmarkSearch, selectedSearchNameToEdit: selectedSearchNameToEdit }))));
|
|
126
|
+
React.createElement(ConfirmationServiceProvider, null, isSaveSearchModalOpen && (React.createElement(SaveCaseSearchModal, { isModalOpen: isSaveSearchModalOpen, modalToggle: modalToggle, isAdding: isAddingBookmarkSearch, selectedSearchNameToEdit: selectedSearchNameToEdit })))));
|
|
125
127
|
}
|
|
@@ -65,7 +65,7 @@ export function CaseSearch() {
|
|
|
65
65
|
setSearchType(newType);
|
|
66
66
|
};
|
|
67
67
|
// To check is Search Button is disabled or not
|
|
68
|
-
const isSearchButtonDisabled = isEmpty(filterQueryInfo.queryString) && isEmpty(searchVal.trim());
|
|
68
|
+
const isSearchButtonDisabled = isEmpty(filterQueryInfo.queryString) && isEmpty(searchVal === null || searchVal === void 0 ? void 0 : searchVal.trim());
|
|
69
69
|
// To handle return or enter keydown event when search button is disabled
|
|
70
70
|
const handleSearchInputKeyDown = (e) => {
|
|
71
71
|
const key = e.which;
|
|
@@ -82,7 +82,7 @@ export function CaseSearch() {
|
|
|
82
82
|
const renderBasicSearch = () => {
|
|
83
83
|
return (React.createElement(React.Fragment, null,
|
|
84
84
|
React.createElement("div", { className: "case-search-input-container" },
|
|
85
|
-
React.createElement(SearchInput, { className: "pf-u-w-100", placeholder: t('Search by keyword or case ID'), value: searchVal.trim(), "data-tracking-id": "search-cases-text-input", id: "case-search-basic", "aria-label": t('Search by keyword or case ID'), onChange: onSearchValChange, onClear: clearSearchVal }),
|
|
85
|
+
React.createElement(SearchInput, { className: "pf-u-w-100", placeholder: t('Search by keyword or case ID'), value: searchVal === null || searchVal === void 0 ? void 0 : searchVal.trim(), "data-tracking-id": "search-cases-text-input", id: "case-search-basic", "aria-label": t('Search by keyword or case ID'), onChange: onSearchValChange, onClear: clearSearchVal }),
|
|
86
86
|
React.createElement(Button, { variant: "primary", type: "submit", className: "search-btn", "data-tracking-id": "case-list-search-button", isDisabled: isSearchButtonDisabled },
|
|
87
87
|
React.createElement(Trans, null, "Search")),
|
|
88
88
|
canUseAdvancedSearch && (React.createElement(Button, { variant: "link", onClick: () => onSearchTypeChange(CaseSearchQueryType.ADVANCED), isDisabled: isFetching, "data-tracking-id": "case-list-adv-toggle-button" },
|
|
@@ -95,5 +95,5 @@ export function CaseSearch() {
|
|
|
95
95
|
return (React.createElement(React.Fragment, null,
|
|
96
96
|
React.createElement("form", { onSubmit: handleSubmit, onKeyDown: handleSearchInputKeyDown },
|
|
97
97
|
React.createElement("div", { className: "form-group case-search-form-group" }, CaseSearchQueryType.BASIC === searchType ? renderBasicSearch() : renderAdvanceSearch())),
|
|
98
|
-
React.createElement(BookmarkedSearchesSelector, { currentCaseSearchString: searchVal.trim(), currentSearchType: searchType })));
|
|
98
|
+
React.createElement(BookmarkedSearchesSelector, { currentCaseSearchString: searchVal === null || searchVal === void 0 ? void 0 : searchVal.trim(), currentSearchType: searchType })));
|
|
99
99
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SaveCaseSearchModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/case-list/case-search/SaveCaseSearchModal.tsx"],"names":[],"mappings":"AA2BA,UAAU,MAAM;IACZ,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;CACpC;AAED,wBAAgB,mBAAmB,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,wBAAwB,EAAE,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"SaveCaseSearchModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/case-list/case-search/SaveCaseSearchModal.tsx"],"names":[],"mappings":"AA2BA,UAAU,MAAM;IACZ,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;CACpC;AAED,wBAAgB,mBAAmB,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,wBAAwB,EAAE,EAAE,MAAM,eAgQ3G"}
|
|
@@ -13,6 +13,7 @@ import { GlobalMetadataDispatchContext, GlobalMetadataStateContext, updateUserPr
|
|
|
13
13
|
import find from 'lodash/find';
|
|
14
14
|
import findKey from 'lodash/findKey';
|
|
15
15
|
import isEmpty from 'lodash/isEmpty';
|
|
16
|
+
import pickBy from 'lodash/pickBy';
|
|
16
17
|
import React, { useContext, useEffect, useState } from 'react';
|
|
17
18
|
import { Trans, useTranslation } from 'react-i18next';
|
|
18
19
|
import { createUserFriendlyQueryFromFilterState } from '../../../utils/caseSearchUtils';
|
|
@@ -22,14 +23,17 @@ export function SaveCaseSearchModal({ isModalOpen, modalToggle, isAdding, select
|
|
|
22
23
|
const [localSavedSearchName, setLocalSavedSearchName] = useState('');
|
|
23
24
|
const [localDefaultChecked, setLocalDefaultChecked] = useState(false);
|
|
24
25
|
const [isUpdating, setIsUpdating] = useState(false);
|
|
25
|
-
const confirmRemove = useConfirmation();
|
|
26
26
|
const [isDuplicateNameError, setIsDuplicateNameError] = useState(false);
|
|
27
|
-
const
|
|
27
|
+
const [saveButtonIsClicked, setSaveButtonIsClicked] = useState(false);
|
|
28
|
+
const filterState = useContext(CaseListFilterStateContext);
|
|
29
|
+
const { filterQueryInfo, filterInfo, sortInfo } = filterState;
|
|
30
|
+
const { globalMetadataState } = useContext(GlobalMetadataStateContext);
|
|
31
|
+
const { hydraUserPreferences, loggedInUserRights } = globalMetadataState;
|
|
32
|
+
const confirmRemove = useConfirmation();
|
|
28
33
|
const dispatchToGlobalMetadataReducer = useContext(GlobalMetadataDispatchContext);
|
|
29
|
-
const { filterInfo, sortInfo, filterQueryInfo } = useContext(CaseListFilterStateContext);
|
|
30
34
|
const handleSaveSearchNameChange = (value) => {
|
|
31
35
|
setLocalSavedSearchName(value);
|
|
32
|
-
if (previousBookmarkedSearchesObj[value]) {
|
|
36
|
+
if (previousBookmarkedSearchesObj[value] && selectedSearchNameToEdit !== value) {
|
|
33
37
|
setIsDuplicateNameError(true);
|
|
34
38
|
}
|
|
35
39
|
else {
|
|
@@ -55,43 +59,40 @@ export function SaveCaseSearchModal({ isModalOpen, modalToggle, isAdding, select
|
|
|
55
59
|
previousBookmarkedSearchesObj[defaultSavedSearchKey].defaultChecked = false;
|
|
56
60
|
}
|
|
57
61
|
};
|
|
58
|
-
const
|
|
62
|
+
const save = () => __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
setSaveButtonIsClicked(true);
|
|
64
|
+
if (isEmpty(localSavedSearchName.trim()) || isDuplicateNameError)
|
|
65
|
+
return;
|
|
59
66
|
try {
|
|
60
67
|
setIsUpdating(true);
|
|
61
|
-
previousBookmarkedSearchesObj[localSavedSearchName] = Object.assign({ filterState: filterInfo, sortState: sortInfo, defaultChecked: localDefaultChecked }, filterQueryInfo);
|
|
62
68
|
// if new added search has 'set default' true,
|
|
63
69
|
// need to remove old default search if there is any
|
|
64
70
|
localDefaultChecked && setDefaultSearchToFalse();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// need to remove old default search if there is any
|
|
81
|
-
localDefaultChecked && setDefaultSearchToFalse();
|
|
82
|
-
// add new member to obj
|
|
83
|
-
previousBookmarkedSearchesObj[localSavedSearchName] = Object.assign(Object.assign({}, previousBookmarkedSearchesObj[selectedSearchNameToEdit]), { defaultChecked: localDefaultChecked });
|
|
84
|
-
// name changed, need to deleted old obj member
|
|
85
|
-
if (localSavedSearchName !== selectedSearchNameToEdit) {
|
|
86
|
-
delete previousBookmarkedSearchesObj[selectedSearchNameToEdit];
|
|
71
|
+
if (isAdding) {
|
|
72
|
+
previousBookmarkedSearchesObj[localSavedSearchName] = {
|
|
73
|
+
filterState: pickBy(filterState.filterInfo, (value) => value.length !== 0),
|
|
74
|
+
sortState: sortInfo,
|
|
75
|
+
type: filterState.filterQueryInfo.type,
|
|
76
|
+
defaultChecked: localDefaultChecked,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// user can only edit saved search name and `set default` checkbox
|
|
81
|
+
previousBookmarkedSearchesObj[localSavedSearchName] = Object.assign(Object.assign({}, previousBookmarkedSearchesObj[selectedSearchNameToEdit]), { defaultChecked: localDefaultChecked });
|
|
82
|
+
// Because saved search name changed, need to deleted old name obj
|
|
83
|
+
if (localSavedSearchName !== selectedSearchNameToEdit) {
|
|
84
|
+
delete previousBookmarkedSearchesObj[selectedSearchNameToEdit];
|
|
85
|
+
}
|
|
87
86
|
}
|
|
88
87
|
yield preferencesApiCall(previousBookmarkedSearchesObj);
|
|
89
88
|
setIsUpdating(false);
|
|
89
|
+
setSaveButtonIsClicked(false);
|
|
90
90
|
ToastNotification.addSuccessMessage(t('Saved search has been updated successfully'));
|
|
91
91
|
modalToggle();
|
|
92
92
|
}
|
|
93
93
|
catch (e) {
|
|
94
94
|
setIsUpdating(false);
|
|
95
|
+
setSaveButtonIsClicked(false);
|
|
95
96
|
ToastNotification.addDangerMessage(t('Saved search failed to update'));
|
|
96
97
|
modalToggle();
|
|
97
98
|
}
|
|
@@ -103,6 +104,8 @@ export function SaveCaseSearchModal({ isModalOpen, modalToggle, isAdding, select
|
|
|
103
104
|
catchOnCancel: true,
|
|
104
105
|
title: t(`Delete saved search?`),
|
|
105
106
|
description: React.createElement(Trans, null, "This will permanently remove it from your list of saved searches."),
|
|
107
|
+
confirmText: t('Delete'),
|
|
108
|
+
confirmButtonVariant: ButtonVariant.danger,
|
|
106
109
|
});
|
|
107
110
|
try {
|
|
108
111
|
delete previousBookmarkedSearchesObj[localSavedSearchName];
|
|
@@ -118,16 +121,22 @@ export function SaveCaseSearchModal({ isModalOpen, modalToggle, isAdding, select
|
|
|
118
121
|
// on confirm modal, cancel button is clicked
|
|
119
122
|
}
|
|
120
123
|
});
|
|
124
|
+
const closeModal = () => {
|
|
125
|
+
setSaveButtonIsClicked(false);
|
|
126
|
+
setLocalSavedSearchName('');
|
|
127
|
+
modalToggle();
|
|
128
|
+
};
|
|
121
129
|
useEffect(() => {
|
|
122
130
|
var _a;
|
|
123
131
|
setLocalSavedSearchName(selectedSearchNameToEdit);
|
|
124
132
|
setLocalDefaultChecked(((_a = previousBookmarkedSearchesObj[selectedSearchNameToEdit]) === null || _a === void 0 ? void 0 : _a.defaultChecked) || false);
|
|
125
133
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
126
|
-
}, [selectedSearchNameToEdit]);
|
|
127
|
-
return (React.createElement(Modal, { variant: ModalVariant.medium, title: isAdding ? t('Save search and filters') : t('Edit saved search and filters'), isOpen: isModalOpen, onClose:
|
|
128
|
-
React.createElement(Button, { key: "save", variant: ButtonVariant.primary, isLoading: isUpdating, spinnerAriaValueText: hydraUserPreferences.isFetching ? 'Saving' : undefined, isDisabled:
|
|
134
|
+
}, [filterInfo, filterQueryInfo.queryString, isAdding, selectedSearchNameToEdit]);
|
|
135
|
+
return (React.createElement(Modal, { variant: ModalVariant.medium, title: isAdding ? t('Save search and filters') : t('Edit saved search and filters'), isOpen: isModalOpen, onClose: closeModal, style: { overflow: 'visible' }, actions: [
|
|
136
|
+
React.createElement(Button, { key: "save", variant: ButtonVariant.primary, isLoading: isUpdating, spinnerAriaValueText: hydraUserPreferences.isFetching ? 'Saving' : undefined, isDisabled: hydraUserPreferences.isFetching ||
|
|
137
|
+
(saveButtonIsClicked && (isEmpty(localSavedSearchName.trim()) || isDuplicateNameError)), "data-tracking-id": isAdding ? 'case-list-bookmark-search-saved' : 'case-list-bookmark-search-edited', onClick: save },
|
|
129
138
|
React.createElement(Trans, null, "Save")),
|
|
130
|
-
React.createElement(Button, { key: "cancel", variant: ButtonVariant.secondary, "data-tracking-id": "case-list-bookmark-search-canceled", onClick:
|
|
139
|
+
React.createElement(Button, { key: "cancel", variant: ButtonVariant.secondary, "data-tracking-id": "case-list-bookmark-search-canceled", onClick: closeModal },
|
|
131
140
|
React.createElement(Trans, null, "Cancel")),
|
|
132
141
|
React.createElement(React.Fragment, null,
|
|
133
142
|
React.createElement(Checkbox, { className: "pf-u-ml-md save-search-set-default", key: "set-as-default", "aria-label": t('Set as default'), id: "case-list-bookmark-search-set-as-default", "data-tracking-id": "case-list-bookmark-search-set-as-default", isChecked: localDefaultChecked, onChange: (checkbox, e) => {
|
|
@@ -140,9 +149,13 @@ export function SaveCaseSearchModal({ isModalOpen, modalToggle, isAdding, select
|
|
|
140
149
|
React.createElement(Trans, null, "Remove")))),
|
|
141
150
|
] },
|
|
142
151
|
React.createElement(Form, null,
|
|
143
|
-
React.createElement(FormGroup, { label: t('Name'), isRequired: true, fieldId: "save-search-name", validated: isDuplicateNameError ? 'error' : 'default', helperTextInvalid: t('Filter with same name already exists. Please enter a unique name.'), className: "form-group pull-bottom-narrow" },
|
|
144
|
-
React.createElement(TextInput, { isRequired: true, type: "text", placeholder: t('Enter a unique name to reference in the future'), id: "save-search-name", name: "save-search-name", "aria-describedby": "save-search-name-helper", value: localSavedSearchName, onChange: handleSaveSearchNameChange, className: `form-control${isDuplicateNameError ||
|
|
145
|
-
|
|
152
|
+
React.createElement(FormGroup, { label: t('Name'), isRequired: true, fieldId: "save-search-name", validated: saveButtonIsClicked && isDuplicateNameError ? 'error' : 'default', helperTextInvalid: t('Filter with same name already exists. Please enter a unique name.'), className: "form-group pull-bottom-narrow" },
|
|
153
|
+
React.createElement(TextInput, { isRequired: true, type: "text", placeholder: t('Enter a unique name to reference in the future'), id: "save-search-name", name: "save-search-name", "aria-describedby": "save-search-name-helper", value: localSavedSearchName, onChange: handleSaveSearchNameChange, className: `form-control${saveButtonIsClicked && (isDuplicateNameError || isEmpty(localSavedSearchName.trim()))
|
|
154
|
+
? ' form-invalid'
|
|
155
|
+
: ''}`, validated: saveButtonIsClicked && (isDuplicateNameError || isEmpty(localSavedSearchName.trim()))
|
|
156
|
+
? 'error'
|
|
157
|
+
: 'default' })),
|
|
158
|
+
React.createElement(FormGroup, { label: t('Search and filter query'), isRequired: true, fieldId: "filter-query", className: "form-group pf-u-mt-lg", validated: saveButtonIsClicked ? 'error' : 'default' },
|
|
146
159
|
React.createElement(TextArea, { isRequired: true, type: "text", id: "filter-query", name: "filter-query", "aria-describedby": "filter-query-helper", value: isAdding
|
|
147
160
|
? createUserFriendlyQueryFromFilterState(filterInfo, filterQueryInfo.queryString)
|
|
148
161
|
: selectedSearchNameToEdit && previousBookmarkedSearchesObj[selectedSearchNameToEdit]
|
package/lib/esm/css/caseList.css
CHANGED
|
@@ -234,9 +234,9 @@
|
|
|
234
234
|
min-width: 80px;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
.case-search-bottom .case-list-table tr td.pf-c-table__check {
|
|
237
|
+
/* .case-search-bottom .case-list-table tr td.pf-c-table__check {
|
|
238
238
|
padding: 2rem 1rem 1.5rem 2rem !important;
|
|
239
|
-
}
|
|
239
|
+
} */
|
|
240
240
|
|
|
241
241
|
.case-search-bottom .case-list-table .case-number,
|
|
242
242
|
.case-search-bottom .case-list-table .modified-name,
|
|
@@ -20,7 +20,6 @@ export declare const advanceSearchFieldNameToSolrFieldMapping: {
|
|
|
20
20
|
case_24_7: string;
|
|
21
21
|
case_is_cep: string;
|
|
22
22
|
case_accountNumber: string;
|
|
23
|
-
case_type: string;
|
|
24
23
|
case_number: string;
|
|
25
24
|
case_owner_sso_username: string;
|
|
26
25
|
case_lastModifiedByName: string;
|
|
@@ -32,11 +31,13 @@ export declare const advanceSearchFieldNameToSolrFieldMapping: {
|
|
|
32
31
|
case_createdDate: string;
|
|
33
32
|
case_description: string;
|
|
34
33
|
case_summary: string;
|
|
34
|
+
case_alternate_id: string;
|
|
35
35
|
case_product: string;
|
|
36
36
|
case_status: string;
|
|
37
37
|
case_folderNumber: string;
|
|
38
38
|
case_severity: string;
|
|
39
39
|
case_customer_escalation: string;
|
|
40
40
|
case_version: string;
|
|
41
|
+
case_type: string;
|
|
41
42
|
};
|
|
42
43
|
//# sourceMappingURL=caseSearch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caseSearch.d.ts","sourceRoot":"","sources":["../../../src/enums/caseSearch.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,oBAAY,mBAAmB;IAC3B,KAAK,UAAU;IACf,QAAQ,aAAa;CACxB;AAED,eAAO,MAAM,2BAA2B;;;;;;;;;;;;CAYvC,CAAC;AAEF,eAAO,MAAM,wCAAwC
|
|
1
|
+
{"version":3,"file":"caseSearch.d.ts","sourceRoot":"","sources":["../../../src/enums/caseSearch.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,oBAAY,mBAAmB;IAC3B,KAAK,UAAU;IACf,QAAQ,aAAa;CACxB;AAED,eAAO,MAAM,2BAA2B;;;;;;;;;;;;CAYvC,CAAC;AAEF,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;CAiBpD,CAAC"}
|
|
@@ -16,6 +16,6 @@ export const fieldNameToSolrFieldMapping = {
|
|
|
16
16
|
[SolrKeys.version]: 'productVersion',
|
|
17
17
|
[SolrKeys.caseContactSSO]: 'ownedByMe',
|
|
18
18
|
[SolrKeys.createdBySsoUsername]: 'createdBySsoUsername',
|
|
19
|
-
[SolrKeys.type]: '
|
|
19
|
+
[SolrKeys.type]: 'caseType',
|
|
20
20
|
};
|
|
21
|
-
export const advanceSearchFieldNameToSolrFieldMapping = Object.assign(Object.assign({}, fieldNameToSolrFieldMapping), { [SolrKeys.fts]: 'FTS', [SolrKeys.cep]: 'CEP', [SolrKeys.accountNumber]: 'accountNumber', [SolrKeys.
|
|
21
|
+
export const advanceSearchFieldNameToSolrFieldMapping = Object.assign(Object.assign({}, fieldNameToSolrFieldMapping), { [SolrKeys.fts]: 'FTS', [SolrKeys.cep]: 'CEP', [SolrKeys.accountNumber]: 'accountNumber', [SolrKeys.caseNumber]: 'caseNumber', [SolrKeys.caseOwner]: 'ownerSSO', [SolrKeys.modifiedBy]: 'lastModifiedByName', [SolrKeys.createdBySsoUsername]: 'createdBySSO', [SolrKeys.createdBy]: 'createdByName', [SolrKeys.contactName]: 'contactName', [SolrKeys.caseContactSSO]: 'contactSSO', [SolrKeys.modifiedDate]: 'lastModifiedDate', [SolrKeys.createdDate]: 'createdDate', [SolrKeys.description]: 'description', [SolrKeys.caseSummary]: 'summary', [SolrKeys.alternateId]: 'alternateId' });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CaseSearchQueryType } from '../enums/caseSearch';
|
|
2
2
|
export declare function useFilterStateOnLoad(): {
|
|
3
|
-
set: (queryFromUrl: string, pageSizeFromUrl: number, currentPageFromUrl: number, searchType: CaseSearchQueryType) =>
|
|
3
|
+
set: (queryFromUrl: string, pageSizeFromUrl: number, currentPageFromUrl: number, searchType: CaseSearchQueryType) => any;
|
|
4
4
|
};
|
|
5
5
|
//# sourceMappingURL=useFilterStateOnLoad.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFilterStateOnLoad.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFilterStateOnLoad.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFilterStateOnLoad.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFilterStateOnLoad.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI1D,wBAAgB,oBAAoB;wBAkBd,MAAM,mBACH,MAAM,sBACH,MAAM,cACd,mBAAmB;EAsDtC"}
|
|
@@ -3,41 +3,36 @@ import find from 'lodash/find';
|
|
|
3
3
|
import findKey from 'lodash/findKey';
|
|
4
4
|
import isEmpty from 'lodash/isEmpty';
|
|
5
5
|
import { useContext, useMemo } from 'react';
|
|
6
|
-
import {
|
|
6
|
+
import { CaseListFilterStateContext, initialCaseFilterState } from '../components/case-list/CaseListFilterContext';
|
|
7
7
|
import { isArrayHashMapEmpty } from '../components/case-list/CaseListFilterHelpers';
|
|
8
|
-
import { updateFilterState } from '../components/case-list/CaseListFilterReducer';
|
|
9
8
|
import { SolrKeys } from '../enums/filters';
|
|
10
9
|
import { createFilterStateFromUrlQuery } from '../utils/caseSearchUtils';
|
|
11
10
|
export function useFilterStateOnLoad() {
|
|
12
11
|
const { globalMetadataState, globalMetadataState: { caseGroups, hydraUserPreferences }, } = useContext(GlobalMetadataStateContext);
|
|
13
12
|
const filterState = useContext(CaseListFilterStateContext);
|
|
14
|
-
const filterDispatch = useContext(CaseListFilterDispatchContext);
|
|
15
13
|
const savesSearches = find(hydraUserPreferences.data, (pref) => pref.key === UserPreferencesKeys.caseSavedSearchFilters);
|
|
16
14
|
const savedSearchesObj = useMemo(() => ((savesSearches === null || savesSearches === void 0 ? void 0 : savesSearches.value) ? JSON.parse(savesSearches.value) : {}), [savesSearches]);
|
|
17
15
|
const set = (queryFromUrl, pageSizeFromUrl, currentPageFromUrl, searchType) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const hasFilterStateFromQuery = !isArrayHashMapEmpty(filterStateFromQuery.filterInfo) &&
|
|
22
|
-
!isEmpty(filterStateFromQuery.filterQueryInfo.queryString);
|
|
16
|
+
const filterStateFromURL = createFilterStateFromUrlQuery(queryFromUrl, globalMetadataState, pageSizeFromUrl, currentPageFromUrl, searchType);
|
|
17
|
+
const hasFilterStateFromURL = !isArrayHashMapEmpty(filterStateFromURL.filterInfo) &&
|
|
18
|
+
!isEmpty(filterStateFromURL.filterQueryInfo.queryString);
|
|
23
19
|
let savedSearchFilterState = null;
|
|
24
20
|
const defaultSavedSearchKey = findKey(savedSearchesObj, { defaultChecked: true });
|
|
25
21
|
if (defaultSavedSearchKey) {
|
|
26
22
|
const { filterState: filterStateSaved, queryString, type, sortState, } = savedSearchesObj[defaultSavedSearchKey];
|
|
27
|
-
savedSearchFilterState = Object.assign(Object.assign({}, filterState), { sortInfo: sortState, filterQueryInfo: Object.assign(Object.assign({}, filterState.filterQueryInfo), { queryString, type }), filterInfo: filterStateSaved });
|
|
23
|
+
savedSearchFilterState = Object.assign(Object.assign({}, filterState), { sortInfo: sortState, filterQueryInfo: Object.assign(Object.assign({}, filterState.filterQueryInfo), { queryString, type }), filterInfo: Object.assign(Object.assign({}, initialCaseFilterState.filterInfo), filterStateSaved) });
|
|
28
24
|
}
|
|
29
|
-
defaultFilterState =
|
|
30
|
-
?
|
|
25
|
+
let defaultFilterState = hasFilterStateFromURL
|
|
26
|
+
? filterStateFromURL
|
|
31
27
|
: savedSearchFilterState
|
|
32
28
|
? savedSearchFilterState
|
|
33
|
-
:
|
|
29
|
+
: filterState;
|
|
34
30
|
const defaultGroup = (caseGroups.data || []).find((group) => group.isDefault);
|
|
35
31
|
if (defaultGroup) {
|
|
36
32
|
const updatedFilterInfo = Object.assign(Object.assign({}, filterState.filterInfo), { [SolrKeys.group]: [{ key: defaultGroup.groupNum, value: defaultGroup.name }] });
|
|
37
33
|
defaultFilterState = Object.assign(Object.assign({}, filterState), { filterInfo: updatedFilterInfo });
|
|
38
34
|
}
|
|
39
|
-
|
|
40
|
-
updateFilterState(filterDispatch, defaultFilterState);
|
|
35
|
+
return defaultFilterState;
|
|
41
36
|
};
|
|
42
37
|
return {
|
|
43
38
|
set,
|
|
@@ -303,11 +303,11 @@ function createFilterStateFromUrlQuery(urlQuery, globalMetadataState, pageSize,
|
|
|
303
303
|
}
|
|
304
304
|
function createFilterStateFromAdvancedQuery(queryString, globalMetadataState, currentFilterState) {
|
|
305
305
|
const filterObj = parseSolrQuery(queryString);
|
|
306
|
-
const
|
|
306
|
+
const newFilterInfo = {};
|
|
307
307
|
let advanceToBasicQuery = [];
|
|
308
308
|
Object.keys(filterObj || {}).forEach((_key) => {
|
|
309
309
|
if (_key === SolrKeys.product) {
|
|
310
|
-
|
|
310
|
+
newFilterInfo[SolrPivotKeys.product_version] = generateProductVersionPivotValue(filterObj[_key]);
|
|
311
311
|
}
|
|
312
312
|
// if it's an unnamed field we should add it to free text querystring
|
|
313
313
|
else if (_key === '<implicit>') {
|
|
@@ -316,7 +316,7 @@ function createFilterStateFromAdvancedQuery(queryString, globalMetadataState, cu
|
|
|
316
316
|
else {
|
|
317
317
|
// if field is present in this map, it means field is supported in basic search mode too
|
|
318
318
|
if (fieldNameToSolrFieldMapping[_key]) {
|
|
319
|
-
|
|
319
|
+
newFilterInfo[_key] = generateFilterValue(_key, filterObj[_key], globalMetadataState);
|
|
320
320
|
}
|
|
321
321
|
else {
|
|
322
322
|
// if it's supported in basic search mode then add it as a query string in the search input
|
|
@@ -327,7 +327,7 @@ function createFilterStateFromAdvancedQuery(queryString, globalMetadataState, cu
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
});
|
|
330
|
-
const filterState = Object.assign(Object.assign({}, currentFilterState), { filterQueryInfo: Object.assign(Object.assign({}, currentFilterState.filterQueryInfo), { queryString: advanceToBasicQuery.join(' AND '), type: CaseSearchQueryType.BASIC }), filterInfo: Object.assign(Object.assign({},
|
|
330
|
+
const filterState = Object.assign(Object.assign({}, currentFilterState), { filterQueryInfo: Object.assign(Object.assign({}, currentFilterState.filterQueryInfo), { queryString: advanceToBasicQuery.join(' AND '), type: CaseSearchQueryType.BASIC }), filterInfo: Object.assign(Object.assign({}, initialCaseFilterState.filterInfo), newFilterInfo) });
|
|
331
331
|
return filterState;
|
|
332
332
|
}
|
|
333
333
|
function generateFilterValue(solrFieldName, value, globalMetadataState) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rh-support/cases",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.41",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"@patternfly/react-core": "4.194.0",
|
|
54
54
|
"@patternfly/react-table": "4.63.0",
|
|
55
55
|
"@rh-support/api": "0.3.10",
|
|
56
|
-
"@rh-support/components": "1.1.
|
|
57
|
-
"@rh-support/react-context": "0.2.
|
|
56
|
+
"@rh-support/components": "1.1.29",
|
|
57
|
+
"@rh-support/react-context": "0.2.32",
|
|
58
58
|
"@rh-support/types": "0.2.0",
|
|
59
|
-
"@rh-support/user-permissions": "0.2.
|
|
60
|
-
"@rh-support/utils": "0.2.
|
|
59
|
+
"@rh-support/user-permissions": "0.2.23",
|
|
60
|
+
"@rh-support/utils": "0.2.21",
|
|
61
61
|
"i18next": "^19.0.1",
|
|
62
62
|
"localforage": "^1.7.3",
|
|
63
63
|
"lodash": "^4.17.15",
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
"not ie <= 11",
|
|
102
102
|
"not op_mini all"
|
|
103
103
|
],
|
|
104
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "cb0d1a0aad49e869ec8b6f6192c49d710dcf37cb"
|
|
105
105
|
}
|