Skip to content

Commit 584d121

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

File tree

4 files changed

+129
-47
lines changed

4 files changed

+129
-47
lines changed

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

Lines changed: 17 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,10 @@ const ContentCreateWidget = () => {
116120
ibexa.helpers.tooltips.parse(refContentTree.current);
117121
}, []);
118122

123+
if (suggestions) {
124+
contentTypesWithSuggestions.unshift(['Suggestions', suggestions.map(({ data }) => data)]);
125+
}
126+
119127
return (
120128
<div className="ibexa-extra-actions-container">
121129
<div className="ibexa-extra-actions-container__backdrop" hidden={!createContentVisible} onClick={close} />
@@ -160,7 +168,8 @@ const ContentCreateWidget = () => {
160168
</div>
161169
<div className="ibexa-instant-filter__desc">{filtersDescLabel}</div>
162170
<div className="ibexa-instant-filter__items">
163-
{contentTypes.map(([groupName, groupItems]) => {
171+
{contentTypesWithSuggestions.map(([groupName, groupItems], index) => {
172+
const isSuggestionGroup = suggestions.length && index === 0;
164173
const restrictedContentTypeIds = selectedLocation?.permissions?.create.restrictedContentTypeIds ?? [];
165174
const isHiddenGroup = groupItems.every((groupItem) => {
166175
const isNotSearchedName = filterQuery && !groupItem.name.toLowerCase().includes(filterQuery);
@@ -170,7 +179,13 @@ const ContentCreateWidget = () => {
170179
allowedContentTypes && !allowedContentTypes.includes(groupItem.identifier);
171180
const isHiddenByConfig = groupItem.isHidden;
172181

173-
return isNotSearchedName || hasNotPermission || isNotAllowedContentType || isHiddenByConfig;
182+
return (
183+
isNotSearchedName ||
184+
hasNotPermission ||
185+
isNotAllowedContentType ||
186+
isHiddenByConfig ||
187+
(isNotSearchedName && isSuggestionGroup)
188+
);
174189
});
175190

176191
if (isHiddenGroup) {

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

Lines changed: 49 additions & 20 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,38 @@ 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 = () =>
29+
new Promise((resolve) => {
30+
findLocationsByParentLocationId(
31+
{
32+
...restInfo,
33+
parentLocationId: locationData.parentLocationId,
34+
sortClause,
35+
sortOrder,
36+
limit,
37+
offset,
38+
gridView,
39+
},
40+
resolve,
41+
);
42+
});
43+
const getFindSuggestionsPromise = () =>
44+
new Promise((resolve) => {
45+
if (suggestionsStorage[locationData.parentLocationId]) {
46+
resolve(suggestionsStorage[locationData.parentLocationId]);
47+
48+
return;
49+
}
50+
51+
findSuggestions(
52+
{
53+
...restInfo,
54+
},
55+
resolve,
56+
);
57+
});
2658

2759
useEffect(() => {
2860
if (isFetchLocationHookBlocked) {
@@ -43,24 +75,21 @@ export const useFindLocationsByParentLocationIdFetch = (locationData, { sortClau
4375
}
4476

4577
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-
}
60-
61-
dispatch({ type: 'FETCH_END', data: response });
62-
},
63-
);
78+
Promise.all([getFindLocationsPromise(), getFindSuggestionsPromise()]).then(([locations, suggestions]) => {
79+
if (effectCleaned) {
80+
return;
81+
}
82+
83+
const suggestionsResults = suggestions.View.Result.searchHits.searchHit.map(({ value }) => ({
84+
data: ibexa.helpers.contentType.getContentTypeDataByHref(value.Content.ContentType._href),
85+
}));
86+
87+
setSuggestionsStorage((prevState) => ({
88+
...prevState,
89+
[locationData.parentLocationId]: suggestionsResults,
90+
}));
91+
dispatch({ type: 'FETCH_END', data: locations });
92+
});
6493

6594
return () => {
6695
effectCleaned = true;

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,32 @@ 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).then(handleRequestResponse).then(callback).catch(showErrorNotificationAbortWrapper);
420+
};

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)