Commit 10812270 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Generic search improvements: added checkboxes for filtering on users or groups

parent d245dfa9
......@@ -325,7 +325,9 @@ export default {
},
search(input) {
let url = BASE_API_URL + 'search?query=' + input.genericSearch.filter +
'&page=' + input.genericSearch.paginatorPage + '&pageSize=' + input.genericSearch.paginatorPageSize;
'&paginatorPage=' + input.genericSearch.paginatorPage +
'&paginatorPageSize=' + input.genericSearch.paginatorPageSize +
'&users=' + input.genericSearch.users + "&groups=" + input.genericSearch.groups;
return apiRequest({
method: 'GET',
......
<template>
<div class="mt-sm-3">
<b-form inline>
Includes:
<b-form-checkbox class="ml-4" v-model="input.genericSearch.users" @input="updateTypeFilter">users</b-form-checkbox>
<b-form-checkbox class="ml-4" v-model="input.genericSearch.groups" @input="updateTypeFilter">groups</b-form-checkbox>
</b-form>
<div>
<div v-if="model.genericSearchResults.items && model.genericSearchResults.items.length > 0">
<p>Search results:</p>
......@@ -40,7 +45,7 @@ export default {
'$route': 'updateSearchResults'
},
methods: {
openSearchResult: function(result) {
openSearchResult(result) {
switch (result.type) {
case 'GROUP':
this.$store.dispatch('openGroup', result.id);
......@@ -50,7 +55,11 @@ export default {
break;
}
},
updateSearchResults: function() {
updateTypeFilter() {
this.input.genericSearch.paginatorPage = 1;
this.updateSearchResults();
},
updateSearchResults() {
this.$store.dispatch('search', this.$route.query.q);
}
}
......
......@@ -12,7 +12,7 @@
<b-nav-item href="help/index.html" target="blank_" class="mr-4">Help</b-nav-item>
<b-nav-form>
<b-form-input size="sm" class="mr-sm-2" placeholder="Search" v-model.trim="input.genericSearch.filter" @keydown.native.enter.prevent="genericSearch"></b-form-input>
<b-button size="sm" class="my-2 my-sm-0" type="button" v-on:click="genericSearch()">Search</b-button>
<b-button size="sm" type="button" v-on:click="genericSearch()">Search</b-button>
</b-nav-form>
<b-nav-item-dropdown :text="user" right v-if="user">
<b-dropdown-item href="logout">Logout</b-dropdown-item>
......@@ -39,10 +39,8 @@ export default {
this.$router.push('/', () => {});
},
genericSearch() {
this.input.genericSearch.page = 1;
this.input.genericSearch.pageSize = 20;
this.$router.push({ path: '/search', query: { q: this.input.genericSearch.filter } }, () => {});
this.$store.dispatch('search', this.input.genericSearch.filter);
this.$store.commit('setGenericSearchFilter', this.input.genericSearch.filter);
}
}
}
......
......@@ -36,7 +36,9 @@ export default new Vuex.Store({
genericSearch: {
filter: '',
paginatorPage: 1,
paginatorPageSize: 20
paginatorPageSize: 20,
users: true,
groups: true
}
},
loading: false
......@@ -97,6 +99,10 @@ export default new Vuex.Store({
},
setGenericSearchFilter(state, filter) {
state.input.genericSearch.filter = filter;
state.input.genericSearch.paginatorPage = 1;
state.input.genericSearch.paginatorPageSize = 20;
state.input.genericSearch.users = true;
state.input.genericSearch.groups = true;
},
removeInvitedRegistration(state, regId) {
let index = -1;
......@@ -117,7 +123,9 @@ export default new Vuex.Store({
.then(model => commit('updateHomePageModel', model));
},
search({ commit, state }, filter) {
commit('setGenericSearchFilter', filter);
if (state.input.genericSearch.filter !== filter) {
commit('setGenericSearchFilter', filter);
}
client.search(state.input)
.then(results => commit('displaySearchResults', results));
},
......
package it.inaf.ia2.gms.controller;
import it.inaf.ia2.gms.model.request.GenericSearchRequest;
import it.inaf.ia2.gms.model.response.PaginatedData;
import it.inaf.ia2.gms.model.response.SearchResponseItem;
import it.inaf.ia2.gms.model.response.UserSearchResponse;
import it.inaf.ia2.gms.service.SearchService;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
......@@ -23,10 +24,8 @@ public class SearchController {
private SearchService searchService;
@GetMapping(value = "/search", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<SearchResponseItem>> getSearchResults(@RequestParam("query") String query,
@RequestParam("page") int page, @RequestParam("pageSize") int pageSize) {
PaginatedData<SearchResponseItem> response = searchService.search(query, servletRequest.getUserPrincipal().getName(), page, pageSize);
public ResponseEntity<PaginatedData<SearchResponseItem>> getSearchResults(@Valid GenericSearchRequest searchRequest) {
PaginatedData<SearchResponseItem> response = searchService.search(searchRequest, servletRequest.getUserPrincipal().getName());
return ResponseEntity.ok(response);
}
......
package it.inaf.ia2.gms.model.request;
public class GenericSearchRequest extends PaginatedModelRequest {
private String query;
private boolean users;
private boolean groups;
public GenericSearchRequest() {
this.users = true;
this.groups = true;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public boolean isUsers() {
return users;
}
public void setUsers(boolean users) {
this.users = users;
}
public boolean isGroups() {
return groups;
}
public void setGroups(boolean groups) {
this.groups = groups;
}
}
......@@ -8,6 +8,11 @@ public class PaginatedModelRequest {
private int paginatorPage;
private int paginatorPageSize;
public PaginatedModelRequest() {
this.paginatorPage = 1;
this.paginatorPageSize = 20;
}
public int getPaginatorPage() {
return paginatorPage;
}
......
......@@ -14,6 +14,7 @@ import it.inaf.ia2.gms.persistence.PermissionsDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.authn.RapClient;
import it.inaf.ia2.gms.model.request.GenericSearchRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
......@@ -46,15 +47,21 @@ public class SearchService {
/**
* Generic search (both groups and users).
*/
public PaginatedData<SearchResponseItem> search(String query, String userId, int page, int pageSize) {
public PaginatedData<SearchResponseItem> search(GenericSearchRequest searchRequest, String userId) {
List<SearchResponseItem> items = searchUsers(query);
items.addAll(searchGroups(query, userId));
List<SearchResponseItem> items = new ArrayList<>();
if (searchRequest.isUsers()) {
items.addAll(searchUsers(searchRequest.getQuery()));
}
if (searchRequest.isGroups()) {
items.addAll(searchGroups(searchRequest.getQuery(), userId));
}
// sort by label
items.sort((i1, i2) -> i1.getLabel().compareTo(i2.getLabel()));
return new PaginatedData<>(items, page, pageSize);
return new PaginatedData<>(items, searchRequest.getPaginatorPage(), searchRequest.getPaginatorPageSize());
}
private List<SearchResponseItem> searchUsers(String query) {
......
......@@ -8,11 +8,14 @@ import it.inaf.ia2.gms.model.response.UserSearchResponse;
import it.inaf.ia2.gms.service.SearchService;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import org.mockito.InjectMocks;
import org.mockito.Mock;
......@@ -53,13 +56,20 @@ public class SearchControllerTest {
PaginatedData<SearchResponseItem> response = new PaginatedData<>(new ArrayList<>(), 1, 10);
when(searchService.search(any(), any(), anyInt(), anyInt())).thenReturn(response);
when(searchService.search(any(), any())).thenReturn(response);
mockMvc.perform(get("/search?query=searchText&page=1&pageSize=10")
mockMvc.perform(get("/search?query=searchText&paginatorPage=1&paginatorPageSize=10&groups=false")
.contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk());
verify(searchService, times(1)).search(eq("searchText"), eq("admin_id"), eq(1), eq(10));
verify(searchService, times(1)).search(argThat(req -> {
assertEquals("searchText", req.getQuery());
assertEquals(1, req.getPaginatorPage());
assertEquals(10, req.getPaginatorPageSize());
assertTrue(req.isUsers());
assertFalse(req.isGroups());
return true;
}), eq("admin_id"));
}
@Test
......
......@@ -12,6 +12,7 @@ import it.inaf.ia2.gms.persistence.PermissionsDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.authn.RapClient;
import it.inaf.ia2.gms.model.request.GenericSearchRequest;
import it.inaf.ia2.rap.data.Identity;
import it.inaf.ia2.rap.data.IdentityType;
import it.inaf.ia2.rap.data.RapUser;
......@@ -118,7 +119,10 @@ public class SearchServiceTest {
when(permissionsDAO.findUserPermissions(any())).thenReturn(
Collections.singletonList(permission));
PaginatedData<SearchResponseItem> response = searchService.search("foo", "manager_id", 1, 10);
GenericSearchRequest searchRequest = new GenericSearchRequest();
searchRequest.setQuery("foo");
PaginatedData<SearchResponseItem> response = searchService.search(searchRequest, "manager_id");
assertEquals(2, response.getTotalItems());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment