Implemented search users
This commit is contained in:
parent
3e679f2b9a
commit
be203ccf5c
@ -24,4 +24,6 @@ public interface UserRepository {
|
||||
}
|
||||
|
||||
List<RUser> all(RRoom room, Set<UserDetails> details) throws NodeNotFoundException, RoomNotFoundException;
|
||||
|
||||
List<RUser> search(String input, Set<UserDetails> details);
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package ru.dragonestia.picker.api.repository.response;
|
||||
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record SearchUserResponse(List<RUser> users) {}
|
||||
@ -0,0 +1,41 @@
|
||||
package ru.dragonestia.picker.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||
import ru.dragonestia.picker.api.repository.response.SearchUserResponse;
|
||||
import ru.dragonestia.picker.service.UserService;
|
||||
import ru.dragonestia.picker.util.NamingValidator;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
private final NamingValidator namingValidator;
|
||||
|
||||
@GetMapping("/search")
|
||||
SearchUserResponse search(@RequestParam(name = "input") String input,
|
||||
@RequestParam(name = "requiredDetails", required = false, defaultValue = "") String detailsSeq) {
|
||||
|
||||
if (!namingValidator.validateUserId(input) || input.isEmpty()) {
|
||||
return new SearchUserResponse(List.of());
|
||||
}
|
||||
|
||||
var details = new HashSet<UserDetails>();
|
||||
for (var detailStr: detailsSeq.split(",")) {
|
||||
try {
|
||||
details.add(UserDetails.valueOf(detailStr.toUpperCase()));
|
||||
} catch (IllegalArgumentException ignore) {}
|
||||
}
|
||||
|
||||
return new SearchUserResponse(userService.searchUsers(input, details));
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package ru.dragonestia.picker.repository;
|
||||
|
||||
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.model.Room;
|
||||
import ru.dragonestia.picker.model.User;
|
||||
|
||||
@ -19,4 +20,6 @@ public interface UserRepository {
|
||||
void onRemoveRoom(Room room);
|
||||
|
||||
List<User> usersOf(Room room);
|
||||
|
||||
List<User> search(String input);
|
||||
}
|
||||
|
||||
@ -120,6 +120,16 @@ public class UserRepositoryImpl implements UserRepository {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<User> search(String input) {
|
||||
synchronized (usersMap) {
|
||||
return usersMap.keySet().stream()
|
||||
.filter(user -> user.id().startsWith(input))
|
||||
.sorted(Comparator.comparing(User::id))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
private record NodeRoomPath(String node, String bucket) {
|
||||
|
||||
@Override
|
||||
|
||||
@ -21,4 +21,6 @@ public interface UserService {
|
||||
List<User> getRoomUsers(Room room);
|
||||
|
||||
List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details);
|
||||
|
||||
List<RUser> searchUsers(String input, Set<UserDetails> details);
|
||||
}
|
||||
|
||||
@ -56,4 +56,20 @@ public class UserServiceImpl implements UserService {
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RUser> searchUsers(String input, Set<UserDetails> details) {
|
||||
return userRepository.search(input).stream()
|
||||
.map(user -> {
|
||||
var responseUser = user.toResponseObject();
|
||||
|
||||
for (var detail: details) {
|
||||
if (detail == UserDetails.COUNT_ROOMS) {
|
||||
responseUser.putDetail(UserDetails.COUNT_ROOMS, Integer.toString(getUserRooms(user).size()));
|
||||
}
|
||||
}
|
||||
|
||||
return responseUser;
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ public class NamingValidator {
|
||||
throw new InvalidRoomIdentifierException(nodeId, input);
|
||||
}
|
||||
|
||||
private boolean validateUserId(String input) {
|
||||
public boolean validateUserId(String input) {
|
||||
return ValidateIdentifier.forUser(input);
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ public class MainLayout extends AppLayout {
|
||||
private SideNav createSideNav() {
|
||||
var nav = new SideNav();
|
||||
nav.addItem(new SideNavItem("Nodes list", NodesPage.class, VaadinIcon.FOLDER_O.create()));
|
||||
nav.addItem(new SideNavItem("Search users", HomePage.class, VaadinIcon.SEARCH.create()));
|
||||
nav.addItem(new SideNavItem("Search users", UserSearchPage.class, VaadinIcon.SEARCH.create()));
|
||||
nav.addItem(new SideNavItem("Documentation", "https://github.com/ScarletRedMan/RoomPicker", VaadinIcon.BOOK.create()));
|
||||
nav.addItem(new SideNavItem("Sign-out", HomePage.class, VaadinIcon.SIGN_OUT.create()));
|
||||
return nav;
|
||||
|
||||
@ -0,0 +1,73 @@
|
||||
package ru.dragonestia.picker.cp.page;
|
||||
|
||||
import com.vaadin.flow.component.Unit;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.button.ButtonVariant;
|
||||
import com.vaadin.flow.component.grid.ColumnTextAlign;
|
||||
import com.vaadin.flow.component.grid.Grid;
|
||||
import com.vaadin.flow.component.html.Span;
|
||||
import com.vaadin.flow.component.icon.Icon;
|
||||
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.cp.component.Notifications;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@PageTitle("Search users")
|
||||
@Route(value = "/users", layout = MainLayout.class)
|
||||
public class UserSearchPage extends VerticalLayout {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final TextField fieldUsername;
|
||||
private final Grid<RUser> userGrid;
|
||||
private List<RUser> cachedUsers = new LinkedList<>();
|
||||
|
||||
@Autowired
|
||||
public UserSearchPage(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
|
||||
add(fieldUsername = createUsernameInputField());
|
||||
add(userGrid = createUserGrid());
|
||||
}
|
||||
|
||||
private TextField createUsernameInputField() {
|
||||
var field = new TextField();
|
||||
field.setLabel("Username");
|
||||
field.setPlaceholder("some-user-identifier");
|
||||
field.setRequired(true);
|
||||
field.setMinWidth(30, Unit.PERCENTAGE);
|
||||
|
||||
var button = new Button(new Icon(VaadinIcon.SEARCH));
|
||||
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||
button.getStyle().set("color", "#FFFFFF");
|
||||
button.addClickListener(event -> search(fieldUsername.getValue().trim()));
|
||||
|
||||
field.setSuffixComponent(button);
|
||||
return field;
|
||||
}
|
||||
|
||||
private Grid<RUser> createUserGrid() {
|
||||
var grid = new Grid<RUser>();
|
||||
|
||||
grid.addColumn(RUser::getId).setHeader("Identifier")
|
||||
.setFooter("Found %s users".formatted(cachedUsers.size()));
|
||||
|
||||
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms");
|
||||
|
||||
grid.addComponentColumn(user -> new Span("buttons")).setHeader("Manage"); // TODO
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
private void search(String input) {
|
||||
userGrid.setItems(cachedUsers = userRepository.search(input, UserRepository.ALL_DETAILS));
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ import org.springframework.http.HttpMethod;
|
||||
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
||||
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
||||
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
||||
import ru.dragonestia.picker.api.repository.response.SearchUserResponse;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
@ -54,4 +55,17 @@ public class UserRepositoryImpl implements UserRepository {
|
||||
params.put("requiredDetails", detailsStr);
|
||||
}).users();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RUser> search(String input, Set<UserDetails> details) {
|
||||
return rest.query("/users/search",
|
||||
HttpMethod.GET,
|
||||
SearchUserResponse.class,
|
||||
params -> {
|
||||
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||
|
||||
params.put("requiredDetails", detailsStr);
|
||||
params.put("input", input);
|
||||
}).users();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user