Skip to content

Commit

Permalink
fix: filter dsiplays only parent notes issue - EXO-75447 - Meeds-io/m…
Browse files Browse the repository at this point in the history
…eeds#2616. (#1226)

Before this change, when open drawer of note filter and serach for a
sub-level note, only first level parent notes are displayed and
sub-level notes are never displayed. To resolve this problem, consume
the rest of the unified search filter service for the published notes
and for the draft filter using the list already retrieved. After this
change, Sub-level notes is displayed in notes filter search results.
  • Loading branch information
akhanfir authored Nov 27, 2024
1 parent a93554a commit 874de42
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public PageList<SearchResult> search(WikiSearchData wikiSearchData) {
wikiSearchData.getUserId(),
wikiSearchData.getTagNames(),
wikiSearchData.isFavorites(),
wikiSearchData.isNotesTreeFilter(),
(int) wikiSearchData.getOffset(),
wikiSearchData.getLimit());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,21 @@ public class WikiElasticSearchServiceConnector extends ElasticSearchServiceConne
}
""";

public static final String SEARCH_QUERY_TERM_FOR_NOTES_APPLICATION = """
,"must": [
@wildcard_query@
]
""";

public static final String WILDCARD_QUERY = """
{
"wildcard": {
"name": "*@term@*"
}
}
""";



public WikiElasticSearchServiceConnector(ConfigurationManager configurationManager,
InitParams initParams,
Expand Down Expand Up @@ -120,13 +135,13 @@ protected String getSourceFields() {
return StringUtils.join(sourceFields, ",");
}

public List<SearchResult> searchWiki(String searchedText, String userId, List<String> tagNames, boolean isFavorites, int offset, int limit) {
return filteredWikiSearch(searchedText, userId, tagNames, isFavorites, offset, limit);
public List<SearchResult> searchWiki(String searchedText, String userId, List<String> tagNames, boolean isFavorites, boolean isNotesTreeFilter, int offset, int limit) {
return filteredWikiSearch(searchedText, userId, tagNames, isFavorites, isNotesTreeFilter, offset, limit);
}

protected List<SearchResult> filteredWikiSearch(String query, String userId, List<String> tagNames, boolean isFavorites, int offset, int limit) {
protected List<SearchResult> filteredWikiSearch(String query, String userId, List<String> tagNames, boolean isFavorites,boolean isNotesTreeFilter , int offset, int limit) {
Set<String> ids = getUserSpaceIds(userId);
String esQuery = buildQueryStatement(ids, userId, tagNames, query, isFavorites, offset, limit);
String esQuery = buildQueryStatement(ids, userId, tagNames, query, isFavorites, isNotesTreeFilter,offset, limit);
String jsonResponse = getClient().sendRequest(esQuery, getIndex());
return buildWikiResult(jsonResponse);
}
Expand All @@ -153,33 +168,57 @@ private String buildTagsQueryStatement(List<String> values) {
.toString();
}

private String buildTermQuery(String termQuery) {
private String buildTermQuery(String termQuery, boolean isNotesTreeFilter) {
if (StringUtils.isBlank(termQuery)) {
return "";
}

termQuery = removeSpecialCharacters(termQuery);
if (isNotesTreeFilter) {
termQuery = termQuery.trim().replaceAll("\\s+", " ");
List<String> listTermQuery = List.of(termQuery.split(" "));
if (listTermQuery.size() == 0) {
return "";
}
String allWildcardQuery = "";
String termWildcardQuery = WILDCARD_QUERY.replace("@term@",listTermQuery.get(0));
allWildcardQuery = allWildcardQuery.concat(termWildcardQuery);
if (listTermQuery.size() > 1) {
int index = 0;
for(String term : listTermQuery) {
if (index > 0){
termWildcardQuery = WILDCARD_QUERY.replace("@term@", term);
allWildcardQuery = allWildcardQuery.concat(",").concat(termWildcardQuery);
}
index++;
};
}
return SEARCH_QUERY_TERM_FOR_NOTES_APPLICATION.replace("@wildcard_query@", allWildcardQuery);
} else {
List<String> termsQuery = Arrays.stream(termQuery.split(" ")).filter(StringUtils::isNotBlank).map(word -> {
word = word.trim();
if (word.length() > 5) {
word = word + "~1";
}
return word;
}).toList();
return SEARCH_QUERY_TERM.replace("@term@", StringUtils.join(termsQuery, " "));
return SEARCH_QUERY_TERM.replace("@term@", StringUtils.join(termsQuery, " "));
}
}

private String buildQueryStatement(Set<String> calendarOwnersOfUser,
String userId,
List<String> tagNames,
String term,
boolean isFavorites,
boolean isNotesTreeFilter,
long offset,
long limit) {
term = removeSpecialCharacters(term);
Map<String, List<String>> metadataFilters = buildMetadataFilter(isFavorites, userId);
String metadataQuery = buildMetadataQueryStatement(metadataFilters);
String tagsQuery = buildTagsQueryStatement(tagNames);
String termsQuery = buildTermQuery(term);
String termsQuery = buildTermQuery(term, isNotesTreeFilter);
return retrieveSearchQuery().replace("@term_query@", termsQuery)
.replace("@metadatas_query@", metadataQuery)
.replace("@tags_query@", tagsQuery)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1270,14 +1270,17 @@ public Response searchData(@Context
int limit, @QueryParam("wikiType")
String wikiType, @QueryParam("wikiOwner")
String wikiOwner, @QueryParam("favorites")
boolean favorites, @QueryParam("tags") List<String> tagNames) throws Exception {
boolean favorites, @QueryParam("tags")
List<String> tagNames, @QueryParam("isNotesTreeFilter")
boolean isNotesTreeFilter) throws Exception {
limit = limit > 0 ? limit : RestUtils.getLimit(uriInfo);
try {

keyword = keyword.toLowerCase();
Identity currentIdentity = ConversationState.getCurrent().getIdentity();
WikiSearchData data = new WikiSearchData(keyword, currentIdentity.getUserId());
data.setLimit(limit);
data.setNotesTreeFilter(isNotesTreeFilter);
data.setFavorites(favorites);
data.setTagNames(tagNames);
List<SearchResult> results = noteService.search(data).getAll();
Expand All @@ -1296,6 +1299,7 @@ public Response searchData(@Context
TitleSearchResult titleSearchResult = new TitleSearchResult();
titleSearchResult.setTitle(attachment.getName());
titleSearchResult.setId(page.getId());
titleSearchResult.setPageName(page.getName());
titleSearchResult.setActivityId(page.getActivityId());
titleSearchResult.setType(searchResult.getType());
titleSearchResult.setUrl(attachment.getDownloadURL());
Expand All @@ -1319,6 +1323,8 @@ public Response searchData(@Context
TitleSearchResult titleSearchResult = new TitleSearchResult();
titleSearchResult.setTitle(searchResult.getTitle());
titleSearchResult.setId(page.getId());
titleSearchResult.setPageName(page.getName());
titleSearchResult.setPageName(page.getName());
titleSearchResult.setActivityId(page.getActivityId());
if (posterIdentity != null) {
titleSearchResult.setPoster(posterIdentity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class SearchData {

private List<String> tagNames;

private boolean isNotesTreeFilter;

public SearchData(String title, String content, String wikiType, String wikiOwner, String pageId, String userId) {
this.title = org.exoplatform.wiki.utils.Utils.escapeIllegalCharacterInQuery(title);
this.content = org.exoplatform.wiki.utils.Utils.escapeIllegalCharacterInQuery(content);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ public class TitleSearchResult {

private String lang;

private String pageName;

}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ protected String getPermissionFilter() {
// when
List<String> tagNames = new ArrayList<>();
tagNames.add("testNoteTag");
List<SearchResult> searchResults = searchServiceConnector.searchWiki("*","__system", tagNames, false, 0, 20);
List<SearchResult> searchResults = searchServiceConnector.searchWiki("*","__system", tagNames, false, false, 0, 20);

// Then
assertNotNull(searchResults);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void testSearchData() throws Exception {
// When
List<String> tagNames = new ArrayList<>();
tagNames.add("testTag");
Response response = wikiRestService.searchData(uriInfo, "wiki", 10, "page", "alioua", false, tagNames);
Response response = wikiRestService.searchData(uriInfo, "wiki", 10, "page", "alioua", false, tagNames, false);

// Then
assertEquals(200, response.getStatus());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ public void testSearchData() throws Exception {
anyString()))
.thenReturn(identityEntity);

Response response = notesRestService.searchData(uriInfo, "test", 10, "wikiType", "wikiOwner", true, new ArrayList<>());
Response response = notesRestService.searchData(uriInfo, "test", 10, "wikiType", "wikiOwner", true, new ArrayList<>(), false);
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
}

Expand Down
16 changes: 15 additions & 1 deletion notes-webapp/src/main/webapp/javascript/eXo/wiki/notesService.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { notesConstants } from './notesConstants.js';

export function getNote(noteBookType, noteBookOwner, noteId,source,lang) {
let url = `${notesConstants.PORTAL}/${notesConstants.PORTAL_REST}/notes/note/${noteBookType}/${noteBookOwner}/${noteId}`;
let url = `${notesConstants.PORTAL}/${notesConstants.PORTAL_REST}/notes/note/${noteBookType}/${noteBookOwner}/${noteId}`;
if (source){
url=`${url}?source=${source}`;
}
Expand Down Expand Up @@ -429,3 +429,17 @@ export function removeNoteFeaturedImage(noteId, isDraft, lang) {
}
});
}

export function searchNotes(keyword, limit) {
document.dispatchEvent(new CustomEvent('displayTopBarLoading'));
return fetch(`${notesConstants.PORTAL}/${notesConstants.PORTAL_REST}/notes/contextsearch?keyword=${keyword}&isNotesTreeFilter=true&limit=${limit}`, {
method: 'GET',
credentials: 'include',
}).then(resp => {
if (!resp || !resp.ok) {
throw new Error('Response code indicates a server error', resp);
} else {
return resp.json();
}
}).finally(() => document.dispatchEvent(new CustomEvent('hideTopBarLoading')));
}
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,12 @@ export default {
dataCreated: false,
isLoading: false,
selectionType: 'independent',
inProgressTreeFetches: []
inProgressTreeFetches: [],
filterItems: [],
filterItemsDraft: [],
limit: 20,
timeout: 1000,
searchTimer: null,
}),
props: {
selectedTranslation: {
Expand Down Expand Up @@ -498,7 +503,7 @@ export default {
},
active() {
return this.search
&& this.allItems
&& this.allItems
&& this.allItems.filter(item => item.name.toLowerCase().match(this.search.toLowerCase()))
|| this.activeItem;
},
Expand Down Expand Up @@ -533,24 +538,26 @@ export default {
this.isLoading = this.inProgressTreeFetches?.length;
},
search() {
clearTimeout(this.searchTimer);
this.showTree = true;
if (this.search) {
this.items = this.active;
this.items.forEach(item => {
item.children = null;
});
this.showTree = !!this.active.length;
this.searchTerm();
} else {
this.retrieveNoteTree(this.note.wikiType, this.note.wikiOwner, this.note.name);
}
},
filter() {
if (this.note && this.note.id) {
if (this.note.draftPage) {
this.getDraftNote(this.note.id);
} else {
this.getNoteById(this.note.id);
if (!this.search) {
this.items = [];
if (this.note && this.note.id) {
if (this.note.draftPage) {
this.getDraftNote(this.note.id);
} else {
this.getNoteById(this.note.id);
}
}
} else {
this.searchTerm();
}
},
},
Expand Down Expand Up @@ -822,6 +829,9 @@ export default {
}
if (this.isDraftFilter) {
this.naturalSort(this.items);
this.filterItems = this.items;
this.filterItemsDraft = [];
this.filterItemsForSearch(this.filterItems);
}
this.allItems = data.treeNodeData;
this.allItemsHome = data.jsonList[0].children;
Expand Down Expand Up @@ -892,6 +902,49 @@ export default {
this.exporting = false;
this.$nextTick().then(() => this.close());
}
},
searchTerm() {
this.items = [];
this.isLoading = true;
this.searchTimer = setTimeout(() => {
if (this.isDraftFilter) {
this.items = this.filterItemsDraft.filter(item => item.name.includes(this.search));
} else {
this.$notesService.searchNotes(this.search, this.limit).then(data => {
this.items = data?.jsonList.length ? this.toListNotes(data?.jsonList) : [];
this.showTree = !!this.items.length;
});
}
this.isLoading = false;
}, this.timeout);
},
filterItemsForSearch(filterItems){
filterItems.forEach(filterItem => {
if (filterItem.draftPage) {
this.filterItemsDraft.push(filterItem);
}
if (filterItem.hasChild) {
this.filterItemsForSearch(filterItem.children);
}
});
},
toListNotes(items) {
const itemsNotes = [];
items.forEach(item => itemsNotes.push(this.toNote(item)));
return itemsNotes;
},
toNote(note) {
return {
children: [],
disabled: false,
draftPage: false,
name: note.title,
nodeType: note.type,
noteId: note.id,
url: note.url,
path: note.pageName,
parentPageId: ''
};
}
}
};
Expand Down

0 comments on commit 874de42

Please sign in to comment.