@blaze-cms/plugin-search-ui 0.128.1-alpha.0 → 0.129.0-admin-updates.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/lib/components/SearchAdmin/SearchAdmin.js +57 -12
  3. package/lib/components/SearchAdmin/SearchAdmin.js.map +1 -1
  4. package/lib/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js +113 -0
  5. package/lib/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js.map +1 -0
  6. package/lib/components/SearchAdmin/SearchAdminSideBar/index.js +12 -0
  7. package/lib/components/SearchAdmin/SearchAdminSideBar/index.js.map +1 -0
  8. package/lib/components/SearchAdmin/SearchResults/SearchResults.js +18 -6
  9. package/lib/components/SearchAdmin/SearchResults/SearchResults.js.map +1 -1
  10. package/lib/components/useSearch/useSearch.js +11 -5
  11. package/lib/components/useSearch/useSearch.js.map +1 -1
  12. package/lib/components/useSearchResults/useSearchResults.js +1 -19
  13. package/lib/components/useSearchResults/useSearchResults.js.map +1 -1
  14. package/lib-es/components/SearchAdmin/SearchAdmin.js +31 -3
  15. package/lib-es/components/SearchAdmin/SearchAdmin.js.map +1 -1
  16. package/lib-es/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js +76 -0
  17. package/lib-es/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js.map +1 -0
  18. package/lib-es/components/SearchAdmin/SearchAdminSideBar/index.js +3 -0
  19. package/lib-es/components/SearchAdmin/SearchAdminSideBar/index.js.map +1 -0
  20. package/lib-es/components/SearchAdmin/SearchResults/SearchResults.js +18 -6
  21. package/lib-es/components/SearchAdmin/SearchResults/SearchResults.js.map +1 -1
  22. package/lib-es/components/useSearch/useSearch.js +5 -2
  23. package/lib-es/components/useSearch/useSearch.js.map +1 -1
  24. package/lib-es/components/useSearchResults/useSearchResults.js +1 -11
  25. package/lib-es/components/useSearchResults/useSearchResults.js.map +1 -1
  26. package/package.json +5 -5
  27. package/src/components/SearchAdmin/SearchAdmin.js +70 -40
  28. package/src/components/SearchAdmin/SearchAdminSideBar/SearchAdminSideBar.js +88 -0
  29. package/src/components/SearchAdmin/SearchAdminSideBar/index.js +3 -0
  30. package/src/components/SearchAdmin/SearchResults/SearchResults.js +42 -6
  31. package/src/components/useSearch/useSearch.js +8 -2
  32. package/src/components/useSearchResults/useSearchResults.js +1 -15
@@ -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([]);
17
+
13
18
  const [recentSearches, setRecentSearches] = useLocalStorage('recentSearches', []);
14
19
  const [displaySearchModalFrame, setDisplaySearchModalFrame] = useState(false);
15
20
  const [enableResults, setEnableResults] = useState(true);
16
21
  const searchInputRef = useRef(null);
22
+ const debouncedEntityValues = useDebounce(entityValues, 500);
17
23
  const [{ loading, results, total }, setQueryParams] = useSearchResults({
18
- queryKey: SEARCH_ADMIN
24
+ queryKey: SEARCH_ADMIN,
25
+ entities: debouncedEntityValues.map(e => e.id)
19
26
  });
20
27
 
21
28
  useEffect(
@@ -68,6 +75,10 @@ const SearchAdmin = () => {
68
75
  'modal--show': displaySearchModalFrame
69
76
  });
70
77
 
78
+ const searchModalSideBarClassName = classnames('modal__search__sidebar', {
79
+ 'modal__search__sidebar--close': !openSearchSideBar
80
+ });
81
+
71
82
  const isEmptySearchTermAndData = !searchTerm && !results.length;
72
83
  const isEmptySearchTermnAndDisabledResults = !searchTerm && !enableResults;
73
84
  const shouldDisplayRecentSearches =
@@ -75,51 +86,70 @@ const SearchAdmin = () => {
75
86
 
76
87
  const showResults = enableResults && results.length;
77
88
 
89
+ const handleSetEntityValues = newEntity => {
90
+ const entityExists = entityValues.some(entity => entity.id === newEntity.id);
91
+ if (entityExists) {
92
+ setEntityValues(entityValues.filter(entity => entity.id !== newEntity.id));
93
+ } else {
94
+ setEntityValues([...entityValues, newEntity]);
95
+ }
96
+ };
97
+
78
98
  return (
79
99
  <div className="search search--header">
80
100
  <TriggerModal toggleSearchModal={toggleSearchModal} />
81
101
  <div className={searchModalResultsClassName}>
82
102
  {displaySearchModalFrame && (
83
- <>
84
- <div className="modal__header modal__header--search">
85
- <SearchBar
86
- toggleSearchModal={toggleSearchModal}
87
- handleKeyDown={handleKeyDown}
88
- searchInputRef={searchInputRef}
89
- handleSearchTerm={handleSearchTerm}
90
- searchTerm={searchTerm}
91
- search={() => search({ value: searchTerm })}
92
- />
93
- </div>
94
- {shouldDisplayRecentSearches ? (
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>
103
+ <div className="modal__search">
104
+ <SearchAdminSideBar
105
+ searchModalSideBarClassName={searchModalSideBarClassName}
106
+ openSearchSideBar={openSearchSideBar}
107
+ setOpenSearchSideBar={setOpenSearchSideBar}
108
+ handleSetEntityValues={handleSetEntityValues}
109
+ entityValues={entityValues}
110
+ setEntityValues={setEntityValues}
111
+ />
112
+ <div className="modal__search__content">
113
+ <div className="modal__header modal__header--search">
114
+ <SearchBar
115
+ toggleSearchModal={toggleSearchModal}
116
+ handleKeyDown={handleKeyDown}
117
+ searchInputRef={searchInputRef}
118
+ handleSearchTerm={handleSearchTerm}
119
+ searchTerm={searchTerm}
120
+ search={() => search({ value: searchTerm })}
121
+ />
122
+ </div>
123
+ {shouldDisplayRecentSearches ? (
124
+ <RecentSearches
125
+ recentSearches={recentSearches}
126
+ handleSearchTerm={handleSearchTerm}
127
+ search={search}
128
+ />
129
+ ) : (
130
+ <>
131
+ {!showResults && (
132
+ <div className="list list--search">
133
+ <div className="header header--list">
134
+ <h2>No Results</h2>
135
+ </div>
106
136
  </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
- </>
137
+ )}
138
+ </>
139
+ )}
140
+ {showResults && (
141
+ <SearchResults
142
+ currentValue={searchTerm}
143
+ searchTerm={searchTerm}
144
+ loading={loading}
145
+ results={results}
146
+ total={total}
147
+ setQueryParams={setQueryParams}
148
+ closeModal={toggleSearchModal}
149
+ />
150
+ )}
151
+ </div>
152
+ </div>
123
153
  )}
124
154
  </div>
125
155
  </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;
@@ -0,0 +1,3 @@
1
+ import SearchAdminSideBar from './SearchAdminSideBar';
2
+
3
+ export default SearchAdminSideBar;
@@ -54,7 +54,9 @@ const SearchResults = ({
54
54
  {loading && <span>Loading...</span>}
55
55
  <div className="modal__content modal__content--search">
56
56
  <div className="header header--list">
57
- <h2>{total} results</h2>
57
+ <h2 className="header--list--results">
58
+ About <b>{total}</b> search keywords results
59
+ </h2>
58
60
  </div>
59
61
  <VirtualList
60
62
  width="100%"
@@ -65,15 +67,24 @@ const SearchResults = ({
65
67
  scrollToIndex={currentIndex}
66
68
  onItemsRendered={handleRenderedItems}
67
69
  renderItem={({ index, style }) => {
68
- const { id, docType, updated, name } = results[index];
70
+ const {
71
+ id,
72
+ docType,
73
+ updated,
74
+ name,
75
+ entityIdentifier,
76
+ published,
77
+ created,
78
+ status
79
+ } = results[index];
69
80
  const updatedDate = updated ? getDateFormat(updated) : null;
81
+ const createdDate = created ? getDateFormat(created) : null;
82
+ const publishedDate = published ? getDateFormat(published) : null;
70
83
  return (
71
84
  <div key={index} style={style} className="list__item--resultWrapper">
72
85
  <div className="list__item list__item--result">
73
86
  <div className="list__item-row list__item-row--result">
74
- <span className="badge badge--primary">
75
- {docType} {updatedDate}
76
- </span>
87
+ <span className="list__item-identifier">{entityIdentifier}</span>
77
88
  <a
78
89
  href={getNavigationRoute({
79
90
  id,
@@ -85,9 +96,34 @@ const SearchResults = ({
85
96
  docType
86
97
  })
87
98
  }
88
- className="list__item-text list__item-text--result">
99
+ className="list__item-link">
89
100
  {name}
90
101
  </a>
102
+
103
+ <div className="list__item-dates">
104
+ {publishedDate && (
105
+ <span>
106
+ <b>Published: </b>
107
+ {publishedDate}
108
+ </span>
109
+ )}
110
+ <span>
111
+ <b>Created: </b>
112
+ {createdDate}
113
+ </span>
114
+ <span>
115
+ <b>Updated: </b>
116
+ {updatedDate}
117
+ </span>
118
+ </div>
119
+ <div className="list__item-status">
120
+ {status && (
121
+ <span>
122
+ <b>Status: </b>
123
+ {status}
124
+ </span>
125
+ )}
126
+ </div>
91
127
  </div>
92
128
  </div>
93
129
  </div>
@@ -5,7 +5,9 @@ import searchQueries from '../../application/query';
5
5
  function useSearch({ queryKey, resultKeys, entities = [], fields }) {
6
6
  const [queryParams, setParams] = useState({ limit: 20, offset: 0, value: '' });
7
7
  const [searchedValue, setSearchedValue] = useState(null);
8
+ const [en, setEn] = useState([]);
8
9
  const [previousOffset, setPreviousOffset] = useState(null);
10
+
9
11
  const buildSearchQuery = searchQueries[queryKey];
10
12
  const [
11
13
  getSearchResults,
@@ -28,13 +30,14 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
28
30
  const { limit, offset, value } = queryParams;
29
31
  const isNewValueSet = value && value !== searchedValue;
30
32
  const isNewOffsetSet = previousOffset !== null && offset !== previousOffset;
33
+ const notSameLength = en.length !== entities.length;
31
34
  const parsedEntities = entities.length
32
35
  ? entities.map(entity => ({
33
36
  match: { docType: entity }
34
37
  }))
35
38
  : [];
36
39
 
37
- if (isNewValueSet || isNewOffsetSet) {
40
+ if (isNewValueSet || isNewOffsetSet || notSameLength) {
38
41
  getSearchResults({
39
42
  variables: {
40
43
  limit,
@@ -64,6 +67,7 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
64
67
  });
65
68
  setSearchedValue(value);
66
69
  setPreviousOffset(offset);
70
+ setEn(entities);
67
71
  }
68
72
  },
69
73
  [
@@ -75,7 +79,9 @@ function useSearch({ queryKey, resultKeys, entities = [], fields }) {
75
79
  previousOffset,
76
80
  getSearchResults,
77
81
  entities,
78
- fields
82
+ fields,
83
+ entities.length,
84
+ en.length
79
85
  ]
80
86
  );
81
87
 
@@ -1,4 +1,3 @@
1
- import { useState, useEffect } from 'react';
2
1
  import useSearch from '../useSearch';
3
2
 
4
3
  function useSearchResults({ queryKey, resultKeys, entities, fields }) {
@@ -10,21 +9,8 @@ function useSearchResults({ queryKey, resultKeys, entities, fields }) {
10
9
  },
11
10
  setParams
12
11
  ] = useSearch({ queryKey, resultKeys, entities, fields });
13
- const [currentResults, setCurrentResults] = useState([]);
14
- const [allResults, setAllResults] = useState([]);
15
-
16
- useEffect(
17
- () => {
18
- if (currentResults.length !== results.length) {
19
- setAllResults([...allResults, ...results]);
20
- setCurrentResults(results);
21
- }
22
- },
23
- [allResults, currentResults, currentResults.length, results]
24
- );
25
12
 
26
13
  const clearList = params => {
27
- setAllResults([]);
28
14
  setParams({ ...params, offset: 0 });
29
15
  };
30
16
 
@@ -32,7 +18,7 @@ function useSearchResults({ queryKey, resultKeys, entities, fields }) {
32
18
  params.value !== searchedValue ? clearList(params) : setParams(params);
33
19
  };
34
20
 
35
- return [{ loading, results: allResults, total }, setQueryParams];
21
+ return [{ loading, results, total }, setQueryParams];
36
22
  }
37
23
 
38
24
  export default useSearchResults;