Skip to content

Commit 349bec1

Browse files
committed
IBX-7271: Missing suggestions while creating content in COFT
1 parent 05d42a5 commit 349bec1

File tree

4 files changed

+126
-46
lines changed

4 files changed

+126
-46
lines changed

src/bundle/ui-dev/src/modules/universal-discovery/components/content-create-widget/content.create.widget.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
LoadedLocationsMapContext,
1313
ContentOnTheFlyConfigContext,
1414
AllowedContentTypesContext,
15+
SuggestionsStorageContext,
1516
} from '../../universal.discovery.module';
1617
import Dropdown from '../../../common/dropdown/dropdown';
1718

@@ -30,6 +31,7 @@ const ContentCreateWidget = () => {
3031
const [loadedLocationsMap] = useContext(LoadedLocationsMapContext);
3132
const { allowedLanguages, preselectedLanguage, preselectedContentType } = useContext(ContentOnTheFlyConfigContext);
3233
const allowedContentTypes = useContext(AllowedContentTypesContext);
34+
const [suggestionsStorage] = useContext(SuggestionsStorageContext);
3335
const selectedLocation = loadedLocationsMap.find((loadedLocation) => loadedLocation.parentLocationId === markedLocationId);
3436
const filteredLanguages = languages.filter((language) => {
3537
const userHasPermission =
@@ -107,6 +109,8 @@ const ContentCreateWidget = () => {
107109
value: language.languageCode,
108110
label: language.name,
109111
}));
112+
const contentTypesWithSuggestions = [...contentTypes];
113+
const suggestions = suggestionsStorage[selectedLocation?.parentLocationId];
110114

111115
useEffect(() => {
112116
setSelectedLanguage(preselectedLanguage || firstLanguageCode);
@@ -116,6 +120,13 @@ const ContentCreateWidget = () => {
116120
ibexa.helpers.tooltips.parse(refContentTree.current);
117121
}, []);
118122

123+
if (suggestions) {
124+
contentTypesWithSuggestions.unshift([
125+
'Suggestions',
126+
suggestions.map(({ data }) => data),
127+
]);
128+
}
129+
119130
return (
120131
<div className="ibexa-extra-actions-container">
121132
<div className="ibexa-extra-actions-container__backdrop" hidden={!createContentVisible} onClick={close} />
@@ -160,7 +171,8 @@ const ContentCreateWidget = () => {
160171
</div>
161172
<div className="ibexa-instant-filter__desc">{filtersDescLabel}</div>
162173
<div className="ibexa-instant-filter__items">
163-
{contentTypes.map(([groupName, groupItems]) => {
174+
{contentTypesWithSuggestions.map(([groupName, groupItems], index) => {
175+
const isSuggestionGroup = suggestions.length && index === 0;
164176
const restrictedContentTypeIds = selectedLocation?.permissions?.create.restrictedContentTypeIds ?? [];
165177
const isHiddenGroup = groupItems.every((groupItem) => {
166178
const isNotSearchedName = filterQuery && !groupItem.name.toLowerCase().includes(filterQuery);
@@ -170,7 +182,7 @@ const ContentCreateWidget = () => {
170182
allowedContentTypes && !allowedContentTypes.includes(groupItem.identifier);
171183
const isHiddenByConfig = groupItem.isHidden;
172184

173-
return isNotSearchedName || hasNotPermission || isNotAllowedContentType || isHiddenByConfig;
185+
return isNotSearchedName || hasNotPermission || isNotAllowedContentType || isHiddenByConfig || (isNotSearchedName && isSuggestionGroup);
174186
});
175187

176188
if (isHiddenGroup) {

src/bundle/ui-dev/src/modules/universal-discovery/hooks/useFindLocationsByParentLocationIdFetch.js

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { useEffect, useContext, useReducer } from 'react';
22

3-
import { findLocationsByParentLocationId } from '../services/universal.discovery.service';
4-
import { RestInfoContext, BlockFetchLocationHookContext } from '../universal.discovery.module';
3+
import { findLocationsByParentLocationId, findSuggestions } from '../services/universal.discovery.service';
4+
import { RestInfoContext, BlockFetchLocationHookContext, SuggestionsStorageContext } from '../universal.discovery.module';
55

6+
const { ibexa } = window;
67
const fetchInitialState = {
78
dataFetched: false,
89
data: {},
@@ -22,7 +23,36 @@ const fetchReducer = (state, action) => {
2223
export const useFindLocationsByParentLocationIdFetch = (locationData, { sortClause, sortOrder }, limit, offset, gridView = false) => {
2324
const restInfo = useContext(RestInfoContext);
2425
const [isFetchLocationHookBlocked] = useContext(BlockFetchLocationHookContext);
26+
const [suggestionsStorage, setSuggestionsStorage] = useContext(SuggestionsStorageContext);
2527
const [state, dispatch] = useReducer(fetchReducer, fetchInitialState);
28+
const getFindLocationsPromise = () => new Promise((resolve) => {
29+
findLocationsByParentLocationId(
30+
{
31+
...restInfo,
32+
parentLocationId: locationData.parentLocationId,
33+
sortClause,
34+
sortOrder,
35+
limit,
36+
offset,
37+
gridView,
38+
},
39+
resolve,
40+
);
41+
});
42+
const getFindSuggestionsPromise = () => new Promise((resolve) => {
43+
if (suggestionsStorage[locationData.parentLocationId]) {
44+
resolve(suggestionsStorage[locationData.parentLocationId]);
45+
46+
return;
47+
}
48+
49+
findSuggestions(
50+
{
51+
...restInfo,
52+
},
53+
resolve,
54+
);
55+
})
2656

2757
useEffect(() => {
2858
if (isFetchLocationHookBlocked) {
@@ -43,24 +73,21 @@ export const useFindLocationsByParentLocationIdFetch = (locationData, { sortClau
4373
}
4474

4575
dispatch({ type: 'FETCH_START' });
46-
findLocationsByParentLocationId(
47-
{
48-
...restInfo,
49-
parentLocationId: locationData.parentLocationId,
50-
sortClause,
51-
sortOrder,
52-
limit,
53-
offset,
54-
gridView,
55-
},
56-
(response) => {
57-
if (effectCleaned) {
58-
return;
59-
}
76+
Promise.all([getFindLocationsPromise(), getFindSuggestionsPromise()]).then(([locations, suggestions]) => {
77+
if (effectCleaned) {
78+
return;
79+
}
6080

61-
dispatch({ type: 'FETCH_END', data: response });
62-
},
63-
);
81+
const suggestionsResults = suggestions.View.Result.searchHits.searchHit.map(({ value }) => ({
82+
data: ibexa.helpers.contentType.getContentTypeDataByHref(value.Content.ContentType._href),
83+
}));
84+
85+
setSuggestionsStorage((prevState) => ({
86+
...prevState,
87+
[locationData.parentLocationId]: suggestionsResults,
88+
}));
89+
dispatch({ type: 'FETCH_END', data: locations });
90+
});
6491

6592
return () => {
6693
effectCleaned = true;

src/bundle/ui-dev/src/modules/universal-discovery/services/universal.discovery.service.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,35 @@ export const loadLocationsWithPermissions = ({ token, siteaccess, locationIds, s
389389

390390
fetch(request, { signal }).then(handleRequestResponse).then(callback).catch(showErrorNotificationAbortWrapper);
391391
};
392+
393+
export const findSuggestions = ({ siteaccess, token }, callback) => {
394+
const body = JSON.stringify({
395+
'ViewInput': {
396+
'identifier': 'view_with_aggregation',
397+
'ContentQuery': {
398+
'limit': '2',
399+
'offset': '0',
400+
'Aggregations': [
401+
{
402+
'ContentTypeTermAggregation': {
403+
'name': 'content_type'
404+
}
405+
}
406+
]
407+
}
408+
}
409+
});
410+
411+
const request = new Request(ENDPOINT_CREATE_VIEW, {
412+
method: 'POST',
413+
headers: { ...HEADERS_CREATE_VIEW, 'X-Siteaccess': siteaccess, 'X-CSRF-Token': token },
414+
body,
415+
mode: 'same-origin',
416+
credentials: 'same-origin',
417+
});
418+
419+
fetch(request)
420+
.then(handleRequestResponse)
421+
.then(callback)
422+
.catch(showErrorNotificationAbortWrapper);
423+
};

src/bundle/ui-dev/src/modules/universal-discovery/universal.discovery.module.js

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export const EditOnTheFlyDataContext = createContext();
135135
export const BlockFetchLocationHookContext = createContext();
136136
export const SearchTextContext = createContext();
137137
export const DropdownPortalRefContext = createContext();
138+
export const SuggestionsStorageContext = createContext();
138139

139140
const UniversalDiscoveryModule = (props) => {
140141
const { tabs } = ibexa.adminUiConfig.universalDiscoveryWidget;
@@ -154,6 +155,7 @@ const UniversalDiscoveryModule = (props) => {
154155
props.startingLocationId && props.startingLocationId !== 1 && props.startingLocationId !== props.rootLocationId,
155156
);
156157
const [searchText, setSearchText] = useState('');
158+
const [suggestionsStorage, setSuggestionsStorage] = useState({});
157159
const [loadedLocationsMap, dispatchLoadedLocationsAction] = useLoadedLocationsReducer([
158160
{ parentLocationId: props.rootLocationId, subitems: [] },
159161
]);
@@ -421,40 +423,47 @@ const UniversalDiscoveryModule = (props) => {
421423
setCreateContentVisible,
422424
]}
423425
>
424-
<ContentOnTheFlyDataContext.Provider
426+
<SuggestionsStorageContext.Provider
425427
value={[
426-
contentOnTheFlyData,
427-
setContentOnTheFlyData,
428+
suggestionsStorage,
429+
setSuggestionsStorage
428430
]}
429431
>
430-
<ContentOnTheFlyConfigContext.Provider
431-
value={
432-
props.contentOnTheFly
433-
}
432+
<ContentOnTheFlyDataContext.Provider
433+
value={[
434+
contentOnTheFlyData,
435+
setContentOnTheFlyData,
436+
]}
434437
>
435-
<EditOnTheFlyDataContext.Provider
436-
value={[
437-
editOnTheFlyData,
438-
setEditOnTheFlyData,
439-
]}
438+
<ContentOnTheFlyConfigContext.Provider
439+
value={
440+
props.contentOnTheFly
441+
}
440442
>
441-
<SearchTextContext.Provider
443+
<EditOnTheFlyDataContext.Provider
442444
value={[
443-
searchText,
444-
setSearchText,
445+
editOnTheFlyData,
446+
setEditOnTheFlyData,
445447
]}
446448
>
447-
<DropdownPortalRefContext.Provider
448-
value={
449-
dropdownPortalRef
450-
}
449+
<SearchTextContext.Provider
450+
value={[
451+
searchText,
452+
setSearchText,
453+
]}
451454
>
452-
<Tab />
453-
</DropdownPortalRefContext.Provider>
454-
</SearchTextContext.Provider>
455-
</EditOnTheFlyDataContext.Provider>
456-
</ContentOnTheFlyConfigContext.Provider>
457-
</ContentOnTheFlyDataContext.Provider>
455+
<DropdownPortalRefContext.Provider
456+
value={
457+
dropdownPortalRef
458+
}
459+
>
460+
<Tab />
461+
</DropdownPortalRefContext.Provider>
462+
</SearchTextContext.Provider>
463+
</EditOnTheFlyDataContext.Provider>
464+
</ContentOnTheFlyConfigContext.Provider>
465+
</ContentOnTheFlyDataContext.Provider>
466+
</SuggestionsStorageContext.Provider>
458467
</CreateContentWidgetContext.Provider>
459468
</SelectedLocationsContext.Provider>
460469
</RootLocationIdContext.Provider>

0 commit comments

Comments
 (0)