@blaze-cms/plugin-search-ui 0.131.0 → 0.132.0-admin-updates.1
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/CHANGELOG.md +61 -0
- package/lib/components/SearchAdmin/SearchAdmin.js +71 -21
- package/lib/components/SearchAdmin/SearchAdmin.js.map +1 -1
- package/lib/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js +113 -0
- package/lib/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js.map +1 -0
- package/lib/components/SearchAdmin/SearchAdminSideBar/index.js +12 -0
- package/lib/components/SearchAdmin/SearchAdminSideBar/index.js.map +1 -0
- package/lib/components/SearchAdmin/SearchResults/SearchResults.js +81 -29
- package/lib/components/SearchAdmin/SearchResults/SearchResults.js.map +1 -1
- package/lib/components/useSearch/useSearch.js +30 -19
- package/lib/components/useSearch/useSearch.js.map +1 -1
- package/lib/components/useSearchResults/useSearchResults.js +11 -9
- package/lib/components/useSearchResults/useSearchResults.js.map +1 -1
- package/lib-es/components/SearchAdmin/SearchAdmin.js +44 -12
- package/lib-es/components/SearchAdmin/SearchAdmin.js.map +1 -1
- package/lib-es/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js +76 -0
- package/lib-es/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js.map +1 -0
- package/lib-es/components/SearchAdmin/SearchAdminSideBar/index.js +3 -0
- package/lib-es/components/SearchAdmin/SearchAdminSideBar/index.js.map +1 -0
- package/lib-es/components/SearchAdmin/SearchResults/SearchResults.js +54 -14
- package/lib-es/components/SearchAdmin/SearchResults/SearchResults.js.map +1 -1
- package/lib-es/components/useSearch/useSearch.js +25 -17
- package/lib-es/components/useSearch/useSearch.js.map +1 -1
- package/lib-es/components/useSearchResults/useSearchResults.js +5 -3
- package/lib-es/components/useSearchResults/useSearchResults.js.map +1 -1
- package/package.json +6 -6
- package/src/components/SearchAdmin/SearchAdmin.js +64 -42
- package/src/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js +88 -0
- package/src/components/SearchAdmin/SearchAdminSideBar/index.js +3 -0
- package/src/components/SearchAdmin/SearchResults/SearchResults.js +122 -44
- package/src/components/useSearch/useSearch.js +27 -13
- package/src/components/useSearchResults/useSearchResults.js +13 -4
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import React, { useState, useRef, useEffect } from 'react';
|
|
2
2
|
import classnames from 'classnames';
|
|
3
|
+
import { useDebounce } from '@blaze-react/utils/lib/customHooks';
|
|
3
4
|
import useLocalStorage from '../useLocalStorage';
|
|
4
5
|
import SearchBar from './SearchBar';
|
|
5
6
|
import RecentSearches from './RecentSearches';
|
|
6
7
|
import SearchResults from './SearchResults';
|
|
7
8
|
import TriggerModal from './TriggerModal';
|
|
9
|
+
import SearchAdminSideBar from './SearchAdminSideBar';
|
|
8
10
|
import useSearchResults from '../useSearchResults';
|
|
9
11
|
import { SEARCH_ADMIN } from '../../constants';
|
|
10
12
|
|
|
11
13
|
const SearchAdmin = () => {
|
|
12
14
|
const [searchTerm, setSearchTerm] = useState('');
|
|
15
|
+
const [openSearchSideBar, setOpenSearchSideBar] = useState(true);
|
|
16
|
+
const [entityValues, setEntityValues] = useState([]);
|
|
13
17
|
const [recentSearches, setRecentSearches] = useLocalStorage('recentSearches', []);
|
|
14
18
|
const [displaySearchModalFrame, setDisplaySearchModalFrame] = useState(false);
|
|
15
19
|
const [enableResults, setEnableResults] = useState(true);
|
|
16
20
|
const searchInputRef = useRef(null);
|
|
17
|
-
const
|
|
18
|
-
|
|
21
|
+
const debouncedEntityValues = useDebounce(entityValues, 500);
|
|
22
|
+
const entities = debouncedEntityValues.map(e => e.id);
|
|
23
|
+
const [{ loading, newResults: results = [], total }, setQueryParams] = useSearchResults({
|
|
24
|
+
queryKey: SEARCH_ADMIN,
|
|
25
|
+
entities
|
|
19
26
|
});
|
|
20
27
|
|
|
21
28
|
useEffect(
|
|
@@ -30,11 +37,13 @@ const SearchAdmin = () => {
|
|
|
30
37
|
const handleSearchTerm = ({ target: { value } }) => {
|
|
31
38
|
setSearchTerm(value);
|
|
32
39
|
};
|
|
40
|
+
|
|
33
41
|
const toggleSearchModal = () => {
|
|
34
42
|
setSearchTerm(null);
|
|
35
43
|
setEnableResults(false);
|
|
36
44
|
setDisplaySearchModalFrame(!displaySearchModalFrame);
|
|
37
45
|
};
|
|
46
|
+
|
|
38
47
|
const search = ({ value }) => {
|
|
39
48
|
if (!value) return;
|
|
40
49
|
!enableResults && setEnableResults(true);
|
|
@@ -68,58 +77,71 @@ const SearchAdmin = () => {
|
|
|
68
77
|
'modal--show': displaySearchModalFrame
|
|
69
78
|
});
|
|
70
79
|
|
|
80
|
+
const searchModalSideBarClassName = classnames('modal__search__sidebar', {
|
|
81
|
+
'modal__search__sidebar--close': !openSearchSideBar
|
|
82
|
+
});
|
|
83
|
+
|
|
71
84
|
const isEmptySearchTermAndData = !searchTerm && !results.length;
|
|
72
85
|
const isEmptySearchTermnAndDisabledResults = !searchTerm && !enableResults;
|
|
73
86
|
const shouldDisplayRecentSearches =
|
|
74
87
|
isEmptySearchTermAndData || isEmptySearchTermnAndDisabledResults;
|
|
75
88
|
|
|
76
|
-
const
|
|
89
|
+
const handleSetEntityValues = newEntity => {
|
|
90
|
+
const entityExists = entityValues.some(entity => entity.id === newEntity.id);
|
|
91
|
+
if (entityExists) {
|
|
92
|
+
setQueryParams({ value: searchTerm, offset: 0 });
|
|
93
|
+
setEntityValues(entityValues.filter(entity => entity.id !== newEntity.id));
|
|
94
|
+
} else {
|
|
95
|
+
setQueryParams({ value: searchTerm, offset: 0 });
|
|
96
|
+
setEntityValues([...entityValues, newEntity]);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
77
99
|
|
|
78
100
|
return (
|
|
79
101
|
<div className="search search--header">
|
|
80
102
|
<TriggerModal toggleSearchModal={toggleSearchModal} />
|
|
81
103
|
<div className={searchModalResultsClassName}>
|
|
82
104
|
{displaySearchModalFrame && (
|
|
83
|
-
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
105
|
+
<div className="modal__search">
|
|
106
|
+
<SearchAdminSideBar
|
|
107
|
+
searchModalSideBarClassName={searchModalSideBarClassName}
|
|
108
|
+
openSearchSideBar={openSearchSideBar}
|
|
109
|
+
setOpenSearchSideBar={setOpenSearchSideBar}
|
|
110
|
+
handleSetEntityValues={handleSetEntityValues}
|
|
111
|
+
entityValues={entityValues}
|
|
112
|
+
setEntityValues={setEntityValues}
|
|
113
|
+
/>
|
|
114
|
+
<div className="modal__search__content">
|
|
115
|
+
<div className="modal__header modal__header--search">
|
|
116
|
+
<SearchBar
|
|
117
|
+
toggleSearchModal={toggleSearchModal}
|
|
118
|
+
handleKeyDown={handleKeyDown}
|
|
119
|
+
searchInputRef={searchInputRef}
|
|
120
|
+
handleSearchTerm={handleSearchTerm}
|
|
121
|
+
searchTerm={searchTerm}
|
|
122
|
+
search={() => search({ value: searchTerm })}
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
{shouldDisplayRecentSearches && (
|
|
126
|
+
<RecentSearches
|
|
127
|
+
recentSearches={recentSearches}
|
|
128
|
+
handleSearchTerm={handleSearchTerm}
|
|
129
|
+
search={search}
|
|
130
|
+
/>
|
|
131
|
+
)}
|
|
132
|
+
{enableResults && (
|
|
133
|
+
<SearchResults
|
|
134
|
+
currentValue={searchTerm}
|
|
135
|
+
entities={entities}
|
|
136
|
+
loading={loading}
|
|
137
|
+
results={results}
|
|
138
|
+
total={total}
|
|
139
|
+
setQueryParams={setQueryParams}
|
|
140
|
+
closeModal={toggleSearchModal}
|
|
141
|
+
/>
|
|
142
|
+
)}
|
|
93
143
|
</div>
|
|
94
|
-
|
|
95
|
-
<RecentSearches
|
|
96
|
-
recentSearches={recentSearches}
|
|
97
|
-
handleSearchTerm={handleSearchTerm}
|
|
98
|
-
search={search}
|
|
99
|
-
/>
|
|
100
|
-
) : (
|
|
101
|
-
<>
|
|
102
|
-
{!showResults && (
|
|
103
|
-
<div className="list list--search">
|
|
104
|
-
<div className="header header--list">
|
|
105
|
-
<h2>No Results</h2>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
)}
|
|
109
|
-
</>
|
|
110
|
-
)}
|
|
111
|
-
{showResults && (
|
|
112
|
-
<SearchResults
|
|
113
|
-
currentValue={searchTerm}
|
|
114
|
-
searchTerm={searchTerm}
|
|
115
|
-
loading={loading}
|
|
116
|
-
results={results}
|
|
117
|
-
total={total}
|
|
118
|
-
setQueryParams={setQueryParams}
|
|
119
|
-
closeModal={toggleSearchModal}
|
|
120
|
-
/>
|
|
121
|
-
)}
|
|
122
|
-
</>
|
|
144
|
+
</div>
|
|
123
145
|
)}
|
|
124
146
|
</div>
|
|
125
147
|
</div>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { useQuery } from '@apollo/client';
|
|
3
|
+
import { getQuery } from '@blaze-cms/admin-ui-utils';
|
|
4
|
+
import { Checkbox } from '@blaze-react/checkboxes';
|
|
5
|
+
|
|
6
|
+
const MENU_PERMISSIONS = ['update:any', 'update:own', 'create:any', 'create:own'];
|
|
7
|
+
|
|
8
|
+
const SearchAdminSideBar = ({
|
|
9
|
+
searchModalSideBarClassName,
|
|
10
|
+
openSearchSideBar,
|
|
11
|
+
setOpenSearchSideBar,
|
|
12
|
+
handleSetEntityValues,
|
|
13
|
+
entityValues,
|
|
14
|
+
setEntityValues
|
|
15
|
+
}) => {
|
|
16
|
+
const [loadMore, setLoadMore] = useState(false);
|
|
17
|
+
const { data: { getEntitySchemas = [] } = {}, loading } = useQuery(
|
|
18
|
+
getQuery('GET_USER_EDITABLE_ENTITIES'),
|
|
19
|
+
{
|
|
20
|
+
variables: {
|
|
21
|
+
canDoActions: MENU_PERMISSIONS
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (loading) return null;
|
|
27
|
+
|
|
28
|
+
const filteredEntitiesSchemas = getEntitySchemas.filter(entity => {
|
|
29
|
+
if (Object.keys(entity.extras).length) {
|
|
30
|
+
return entity.extras.searchIndexes.includes('admin');
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const entitiesToShow = filteredEntitiesSchemas.slice(
|
|
36
|
+
0,
|
|
37
|
+
loadMore ? filteredEntitiesSchemas.length : 5
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div className={searchModalSideBarClassName}>
|
|
42
|
+
<div
|
|
43
|
+
className="modal__search__sidebar__button"
|
|
44
|
+
role="button"
|
|
45
|
+
onClick={() => setOpenSearchSideBar(!openSearchSideBar)}>
|
|
46
|
+
<i className="material-icons">
|
|
47
|
+
{openSearchSideBar ? 'keyboard_arrow_left' : 'keyboard_arrow_right'}
|
|
48
|
+
</i>
|
|
49
|
+
</div>
|
|
50
|
+
<div className="modal__search__sidebar__container">
|
|
51
|
+
<div className="modal__search__sidebar__wrapper">
|
|
52
|
+
<div className="modal__search__sidebar__filters">
|
|
53
|
+
<i className="material-icons modal__search__sidebar__icon">tune</i>
|
|
54
|
+
<span>Filters</span>
|
|
55
|
+
</div>
|
|
56
|
+
<div
|
|
57
|
+
className="modal__search__sidebar__clear"
|
|
58
|
+
role="button"
|
|
59
|
+
onClick={() => setEntityValues([])}>
|
|
60
|
+
<span>Clear all</span>
|
|
61
|
+
<i className="material-icons modal__search__sidebar__icon--clear">replay</i>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="modal__search__sidebar__entity-list">
|
|
65
|
+
<h1>Entity list</h1>
|
|
66
|
+
{entitiesToShow.map(entity => (
|
|
67
|
+
<Checkbox
|
|
68
|
+
checked={entityValues.some(_entity => _entity.id === entity.id)}
|
|
69
|
+
label={entity.displayName}
|
|
70
|
+
id={entity.id}
|
|
71
|
+
name={entity.id}
|
|
72
|
+
onChange={({ value: { checked } }) => handleSetEntityValues(entity)}
|
|
73
|
+
/>
|
|
74
|
+
))}
|
|
75
|
+
<div
|
|
76
|
+
className="modal__search__sidebar__more"
|
|
77
|
+
role="button"
|
|
78
|
+
onClick={() => setLoadMore(!loadMore)}>
|
|
79
|
+
<i className="material-icons">{!loadMore ? 'navigate_next' : 'expand_less'}</i>
|
|
80
|
+
<span>{loadMore ? 'Less' : 'More'}</span>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export default SearchAdminSideBar;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
2
2
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
3
|
-
import React, { useState } from 'react';
|
|
3
|
+
import React, { useState, useEffect } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import VirtualList from 'react-tiny-virtual-list';
|
|
6
6
|
import { withRouter } from 'react-router-dom';
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
|
|
14
14
|
const SearchResults = ({
|
|
15
15
|
currentValue,
|
|
16
|
+
entities,
|
|
16
17
|
loading,
|
|
17
18
|
results,
|
|
18
19
|
total,
|
|
@@ -22,12 +23,45 @@ const SearchResults = ({
|
|
|
22
23
|
}) => {
|
|
23
24
|
const [verifiedRanges, setVerifiedRanges] = useState([]);
|
|
24
25
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
26
|
+
const [currentResults, setCurrentResults] = useState('');
|
|
27
|
+
const [allResults, setAllResults] = useState([]);
|
|
28
|
+
const [currentParams, setCurrentParams] = useState('');
|
|
29
|
+
|
|
30
|
+
useEffect(
|
|
31
|
+
() => {
|
|
32
|
+
if (!loading) {
|
|
33
|
+
const newResults = results.map(({ id }) => id).join(',');
|
|
34
|
+
if (currentResults !== newResults) {
|
|
35
|
+
const newParams = `${currentValue},${entities.join(',')}`;
|
|
36
|
+
if (newParams !== currentParams) {
|
|
37
|
+
setAllResults(results);
|
|
38
|
+
setCurrentParams(newParams);
|
|
39
|
+
if (verifiedRanges.length) setVerifiedRanges([]);
|
|
40
|
+
} else {
|
|
41
|
+
setAllResults(allResults.concat(results));
|
|
42
|
+
}
|
|
43
|
+
setCurrentResults(newResults);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
[
|
|
48
|
+
allResults,
|
|
49
|
+
currentParams,
|
|
50
|
+
currentResults,
|
|
51
|
+
currentValue,
|
|
52
|
+
entities,
|
|
53
|
+
loading,
|
|
54
|
+
results,
|
|
55
|
+
total,
|
|
56
|
+
verifiedRanges.length
|
|
57
|
+
]
|
|
58
|
+
);
|
|
25
59
|
|
|
26
60
|
const handleRenderedItems = async ({ startIndex }) => {
|
|
27
|
-
const rowsLength =
|
|
61
|
+
const rowsLength = allResults.length;
|
|
28
62
|
const loadIndex = Math.floor(rowsLength / 2) - SEARCH_RESULTS_OVER_SCAN_BUFFER;
|
|
29
63
|
if (loadIndex > 0 && loadIndex < startIndex && !verifiedRanges.includes(loadIndex)) {
|
|
30
|
-
setQueryParams({ value: currentValue, offset:
|
|
64
|
+
setQueryParams({ value: currentValue, offset: allResults.length });
|
|
31
65
|
setVerifiedRanges([...verifiedRanges, loadIndex]);
|
|
32
66
|
setCurrentIndex(startIndex + SEARCH_RESULTS_OVER_SCAN_BUFFER);
|
|
33
67
|
}
|
|
@@ -49,53 +83,96 @@ const SearchResults = ({
|
|
|
49
83
|
return `${day}.${month}.${year}`;
|
|
50
84
|
};
|
|
51
85
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
<div className="modal__content modal__content--search">
|
|
86
|
+
if (!allResults.length)
|
|
87
|
+
return (
|
|
88
|
+
<div className="list list--search">
|
|
56
89
|
<div className="header header--list">
|
|
57
|
-
<h2>
|
|
90
|
+
<h2>No Results</h2>
|
|
58
91
|
</div>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div className="modal__content modal__content--search">
|
|
97
|
+
<div className="header header--list">
|
|
98
|
+
<h2 className="header--list--results">
|
|
99
|
+
About <b>{total}</b> search keywords results
|
|
100
|
+
</h2>
|
|
101
|
+
</div>
|
|
102
|
+
<VirtualList
|
|
103
|
+
width="100%"
|
|
104
|
+
height={window.innerHeight - SEARCH_RESULTS_ELEMETS_HEIGHT_ABOVE_LIST}
|
|
105
|
+
itemCount={allResults.length}
|
|
106
|
+
itemSize={SEARCH_RESULTS_ITEM_SIZE}
|
|
107
|
+
overscanCount={SEARCH_RESULTS_OVER_SCAN_BUFFER}
|
|
108
|
+
scrollToIndex={currentIndex}
|
|
109
|
+
onItemsRendered={handleRenderedItems}
|
|
110
|
+
renderItem={({ index, style }) => {
|
|
111
|
+
const {
|
|
112
|
+
id,
|
|
113
|
+
docType,
|
|
114
|
+
updated,
|
|
115
|
+
name,
|
|
116
|
+
entityIdentifier,
|
|
117
|
+
published,
|
|
118
|
+
created,
|
|
119
|
+
status
|
|
120
|
+
} = allResults[index];
|
|
121
|
+
const updatedDate = updated ? getDateFormat(updated) : null;
|
|
122
|
+
const createdDate = created ? getDateFormat(created) : null;
|
|
123
|
+
const publishedDate = published ? getDateFormat(published) : null;
|
|
124
|
+
return (
|
|
125
|
+
<div key={index} style={style} className="list__item--resultWrapper">
|
|
126
|
+
<div className="list__item list__item--result">
|
|
127
|
+
<div className="list__item-row list__item-row--result">
|
|
128
|
+
<span className="list__item-identifier">{entityIdentifier}</span>
|
|
129
|
+
<a
|
|
130
|
+
href={getNavigationRoute({
|
|
131
|
+
id,
|
|
132
|
+
docType
|
|
133
|
+
})}
|
|
134
|
+
onClick={() =>
|
|
135
|
+
navigate({
|
|
79
136
|
id,
|
|
80
137
|
docType
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
className="list__item-link">
|
|
141
|
+
{name}
|
|
142
|
+
</a>
|
|
143
|
+
|
|
144
|
+
<div className="list__item-dates">
|
|
145
|
+
{publishedDate && (
|
|
146
|
+
<span>
|
|
147
|
+
<b>Published: </b>
|
|
148
|
+
{publishedDate}
|
|
149
|
+
</span>
|
|
150
|
+
)}
|
|
151
|
+
<span>
|
|
152
|
+
<b>Created: </b>
|
|
153
|
+
{createdDate}
|
|
154
|
+
</span>
|
|
155
|
+
<span>
|
|
156
|
+
<b>Updated: </b>
|
|
157
|
+
{updatedDate}
|
|
158
|
+
</span>
|
|
159
|
+
</div>
|
|
160
|
+
<div className="list__item-status">
|
|
161
|
+
{status && (
|
|
162
|
+
<span>
|
|
163
|
+
<b>Status: </b>
|
|
164
|
+
{status}
|
|
165
|
+
</span>
|
|
166
|
+
)}
|
|
91
167
|
</div>
|
|
92
168
|
</div>
|
|
93
169
|
</div>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
{loading && <span>Loading...</span>}
|
|
175
|
+
</div>
|
|
99
176
|
);
|
|
100
177
|
};
|
|
101
178
|
|
|
@@ -106,7 +183,8 @@ SearchResults.propTypes = {
|
|
|
106
183
|
setQueryParams: PropTypes.func.isRequired,
|
|
107
184
|
closeModal: PropTypes.func.isRequired,
|
|
108
185
|
history: PropTypes.object.isRequired,
|
|
109
|
-
currentValue: PropTypes.string.isRequired
|
|
186
|
+
currentValue: PropTypes.string.isRequired,
|
|
187
|
+
entities: PropTypes.array.isRequired
|
|
110
188
|
};
|
|
111
189
|
|
|
112
190
|
export default withRouter(SearchResults);
|
|
@@ -2,20 +2,28 @@ import { useState, useEffect } from 'react';
|
|
|
2
2
|
import { useLazyQuery } from '@apollo/client';
|
|
3
3
|
import searchQueries from '../../application/query';
|
|
4
4
|
|
|
5
|
-
function useSearch({ queryKey, resultKeys, entities = [], fields }) {
|
|
5
|
+
function useSearch({ queryKey, resultKeys, entities = [], fields, extraFilters }) {
|
|
6
6
|
const [queryParams, setParams] = useState({ limit: 20, offset: 0, value: '' });
|
|
7
7
|
const [searchedValue, setSearchedValue] = useState(null);
|
|
8
|
+
const [previousEntities, setPreviousEntities] = useState([]);
|
|
8
9
|
const [previousOffset, setPreviousOffset] = useState(null);
|
|
9
10
|
const buildSearchQuery = searchQueries[queryKey];
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
|
|
12
|
+
const [getSearchResults, { loading, data = {} } = {}] = useLazyQuery(
|
|
13
|
+
buildSearchQuery({ resultKeys }),
|
|
14
|
+
{ ssr: false }
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const { search } = data;
|
|
18
|
+
|
|
19
|
+
const defaultSearch = {
|
|
20
|
+
results: [],
|
|
21
|
+
jsonResults: null,
|
|
22
|
+
total: 0
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const { results, jsonResults, total } = search ?? defaultSearch;
|
|
26
|
+
|
|
19
27
|
// todo: remove ssr: false once this bug is resolved https://github.com/apollographql/apollo-client/issues/9108
|
|
20
28
|
// without ssr: false clients can hang in ssr.
|
|
21
29
|
|
|
@@ -28,13 +36,14 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
|
|
|
28
36
|
const { limit, offset, value } = queryParams;
|
|
29
37
|
const isNewValueSet = value && value !== searchedValue;
|
|
30
38
|
const isNewOffsetSet = previousOffset !== null && offset !== previousOffset;
|
|
39
|
+
const notSameLength = previousEntities.length !== entities.length;
|
|
31
40
|
const parsedEntities = entities.length
|
|
32
41
|
? entities.map(entity => ({
|
|
33
42
|
match: { docType: entity }
|
|
34
43
|
}))
|
|
35
44
|
: [];
|
|
36
45
|
|
|
37
|
-
if (isNewValueSet || isNewOffsetSet) {
|
|
46
|
+
if (isNewValueSet || isNewOffsetSet || notSameLength) {
|
|
38
47
|
getSearchResults({
|
|
39
48
|
variables: {
|
|
40
49
|
limit,
|
|
@@ -48,7 +57,8 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
|
|
|
48
57
|
query: value,
|
|
49
58
|
fields,
|
|
50
59
|
type: 'most_fields',
|
|
51
|
-
default_operator: 'AND'
|
|
60
|
+
default_operator: 'AND',
|
|
61
|
+
extraFilters
|
|
52
62
|
}
|
|
53
63
|
},
|
|
54
64
|
{
|
|
@@ -64,6 +74,7 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
|
|
|
64
74
|
});
|
|
65
75
|
setSearchedValue(value);
|
|
66
76
|
setPreviousOffset(offset);
|
|
77
|
+
setPreviousEntities(entities);
|
|
67
78
|
}
|
|
68
79
|
},
|
|
69
80
|
[
|
|
@@ -75,7 +86,10 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
|
|
|
75
86
|
previousOffset,
|
|
76
87
|
getSearchResults,
|
|
77
88
|
entities,
|
|
78
|
-
fields
|
|
89
|
+
fields,
|
|
90
|
+
entities.length,
|
|
91
|
+
previousEntities.length,
|
|
92
|
+
extraFilters
|
|
79
93
|
]
|
|
80
94
|
);
|
|
81
95
|
|
|
@@ -2,6 +2,8 @@ import { useState, useEffect } from 'react';
|
|
|
2
2
|
import useSearch from '../useSearch';
|
|
3
3
|
|
|
4
4
|
function useSearchResults({ queryKey, resultKeys, entities, fields }) {
|
|
5
|
+
const [currentResults, setCurrentResults] = useState([]);
|
|
6
|
+
const [allResults, setAllResults] = useState([]);
|
|
5
7
|
const [
|
|
6
8
|
{
|
|
7
9
|
searchedValue,
|
|
@@ -10,8 +12,6 @@ function useSearchResults({ queryKey, resultKeys, entities, fields }) {
|
|
|
10
12
|
},
|
|
11
13
|
setParams
|
|
12
14
|
] = useSearch({ queryKey, resultKeys, entities, fields });
|
|
13
|
-
const [currentResults, setCurrentResults] = useState([]);
|
|
14
|
-
const [allResults, setAllResults] = useState([]);
|
|
15
15
|
|
|
16
16
|
useEffect(
|
|
17
17
|
() => {
|
|
@@ -20,7 +20,7 @@ function useSearchResults({ queryKey, resultKeys, entities, fields }) {
|
|
|
20
20
|
setCurrentResults(results);
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
[allResults, currentResults,
|
|
23
|
+
[allResults, currentResults, results]
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
const clearList = params => {
|
|
@@ -32,7 +32,16 @@ function useSearchResults({ queryKey, resultKeys, entities, fields }) {
|
|
|
32
32
|
params.value !== searchedValue ? clearList(params) : setParams(params);
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
return [
|
|
35
|
+
return [
|
|
36
|
+
{
|
|
37
|
+
loading,
|
|
38
|
+
results: allResults,
|
|
39
|
+
currentResults,
|
|
40
|
+
newResults: results,
|
|
41
|
+
total
|
|
42
|
+
},
|
|
43
|
+
setQueryParams
|
|
44
|
+
];
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
export default useSearchResults;
|