Implemented user details page
This commit is contained in:
parent
be203ccf5c
commit
3b8fa87c5b
@ -3,12 +3,14 @@ package ru.dragonestia.picker.api.repository;
|
|||||||
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
||||||
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
||||||
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface UserRepository {
|
public interface UserRepository {
|
||||||
@ -26,4 +28,8 @@ public interface UserRepository {
|
|||||||
List<RUser> all(RRoom room, Set<UserDetails> details) throws NodeNotFoundException, RoomNotFoundException;
|
List<RUser> all(RRoom room, Set<UserDetails> details) throws NodeNotFoundException, RoomNotFoundException;
|
||||||
|
|
||||||
List<RUser> search(String input, Set<UserDetails> details);
|
List<RUser> search(String input, Set<UserDetails> details);
|
||||||
|
|
||||||
|
RUser find(String userId, Set<UserDetails> details);
|
||||||
|
|
||||||
|
List<RRoom.Short> getLinkedRoomsWithUsers(RUser user, Set<RoomDetails> roomDetails);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
package ru.dragonestia.picker.api.repository.response;
|
||||||
|
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record LinkedRoomsWithUserResponse(List<RRoom.Short> rooms) {}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ru.dragonestia.picker.api.repository.response;
|
||||||
|
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
|
|
||||||
|
public record UserDetailsResponse(RUser user) {}
|
||||||
@ -87,5 +87,5 @@ public class RRoom {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Short(String id, int slots, boolean locked, Map<RoomDetails, String> details) {}
|
public record Short(String id, String nodeId, int slots, boolean locked, Map<RoomDetails, String> details) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
package ru.dragonestia.picker.controller;
|
package ru.dragonestia.picker.controller;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import ru.dragonestia.picker.api.repository.response.LinkedRoomsWithUserResponse;
|
||||||
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.api.repository.response.SearchUserResponse;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.UserDetailsResponse;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
|
import ru.dragonestia.picker.model.Room;
|
||||||
|
import ru.dragonestia.picker.model.User;
|
||||||
import ru.dragonestia.picker.service.UserService;
|
import ru.dragonestia.picker.service.UserService;
|
||||||
|
import ru.dragonestia.picker.util.DetailsParser;
|
||||||
import ru.dragonestia.picker.util.NamingValidator;
|
import ru.dragonestia.picker.util.NamingValidator;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -19,6 +20,7 @@ import java.util.List;
|
|||||||
public class UserController {
|
public class UserController {
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
private final DetailsParser detailsParser;
|
||||||
private final NamingValidator namingValidator;
|
private final NamingValidator namingValidator;
|
||||||
|
|
||||||
@GetMapping("/search")
|
@GetMapping("/search")
|
||||||
@ -29,13 +31,28 @@ public class UserController {
|
|||||||
return new SearchUserResponse(List.of());
|
return new SearchUserResponse(List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
var details = new HashSet<UserDetails>();
|
return new SearchUserResponse(userService.searchUsers(input, detailsParser.parseUserDetails(detailsSeq)));
|
||||||
for (var detailStr: detailsSeq.split(",")) {
|
}
|
||||||
try {
|
|
||||||
details.add(UserDetails.valueOf(detailStr.toUpperCase()));
|
@GetMapping("/{userId}")
|
||||||
} catch (IllegalArgumentException ignore) {}
|
UserDetailsResponse find(@PathVariable(value = "userId") String userId,
|
||||||
|
@RequestParam(value = "requiredDetails", required = false) String detailsSeq) {
|
||||||
|
|
||||||
|
if (!namingValidator.validateUserId(userId)) {
|
||||||
|
return new UserDetailsResponse(new RUser(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SearchUserResponse(userService.searchUsers(input, details));
|
return new UserDetailsResponse(userService.getUserDetails(userId, detailsParser.parseUserDetails(detailsSeq)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{userId}/rooms")
|
||||||
|
LinkedRoomsWithUserResponse roomsOf(@PathVariable(value = "userId") String userId,
|
||||||
|
@RequestParam(value = "requiredDetails", required = false) String detailsSeq) {
|
||||||
|
|
||||||
|
if (!namingValidator.validateUserId(userId)) {
|
||||||
|
return new LinkedRoomsWithUserResponse(List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LinkedRoomsWithUserResponse(userService.getUserRoomsWithDetails(new User(userId), detailsParser.parseRoomDetails(detailsSeq)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,6 @@ public class Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RRoom.Short toShortResponseObject() {
|
public RRoom.Short toShortResponseObject() {
|
||||||
return new RRoom.Short(id, slots.getSlots(), locked, new HashMap<>());
|
return new RRoom.Short(id, nodeId, slots.getSlots(), locked, new HashMap<>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package ru.dragonestia.picker.repository;
|
package ru.dragonestia.picker.repository;
|
||||||
|
|
||||||
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
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.Room;
|
||||||
import ru.dragonestia.picker.model.User;
|
import ru.dragonestia.picker.model.User;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package ru.dragonestia.picker.service;
|
package ru.dragonestia.picker.service;
|
||||||
|
|
||||||
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||||
import ru.dragonestia.picker.model.Room;
|
import ru.dragonestia.picker.model.Room;
|
||||||
@ -14,6 +16,8 @@ public interface UserService {
|
|||||||
|
|
||||||
List<Room> getUserRooms(User user);
|
List<Room> getUserRooms(User user);
|
||||||
|
|
||||||
|
List<RRoom.Short> getUserRoomsWithDetails(User user, Set<RoomDetails> details);
|
||||||
|
|
||||||
int linkUsersWithRoom(Room room, Collection<User> users, boolean force) throws RoomAreFullException;
|
int linkUsersWithRoom(Room room, Collection<User> users, boolean force) throws RoomAreFullException;
|
||||||
|
|
||||||
void unlinkUsersFromRoom(Room room, Collection<User> users);
|
void unlinkUsersFromRoom(Room room, Collection<User> users);
|
||||||
@ -23,4 +27,6 @@ public interface UserService {
|
|||||||
List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details);
|
List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details);
|
||||||
|
|
||||||
List<RUser> searchUsers(String input, Set<UserDetails> details);
|
List<RUser> searchUsers(String input, Set<UserDetails> details);
|
||||||
|
|
||||||
|
RUser getUserDetails(String userId, Set<UserDetails> details);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import ru.dragonestia.picker.api.repository.response.type.RNode;
|
|||||||
import ru.dragonestia.picker.model.Node;
|
import ru.dragonestia.picker.model.Node;
|
||||||
import ru.dragonestia.picker.repository.NodeRepository;
|
import ru.dragonestia.picker.repository.NodeRepository;
|
||||||
import ru.dragonestia.picker.service.NodeService;
|
import ru.dragonestia.picker.service.NodeService;
|
||||||
|
import ru.dragonestia.picker.util.DetailsExtractor;
|
||||||
import ru.dragonestia.picker.util.NamingValidator;
|
import ru.dragonestia.picker.util.NamingValidator;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -21,6 +22,7 @@ import java.util.Set;
|
|||||||
public class NodeServiceImpl implements NodeService {
|
public class NodeServiceImpl implements NodeService {
|
||||||
|
|
||||||
private final NodeRepository nodeRepository;
|
private final NodeRepository nodeRepository;
|
||||||
|
private final DetailsExtractor detailsExtractor;
|
||||||
private final NamingValidator namingValidator;
|
private final NamingValidator namingValidator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -43,13 +45,7 @@ public class NodeServiceImpl implements NodeService {
|
|||||||
public List<RNode> getAllNodesWithDetailsResponse(Set<NodeDetails> details) {
|
public List<RNode> getAllNodesWithDetailsResponse(Set<NodeDetails> details) {
|
||||||
var response = new LinkedList<RNode>();
|
var response = new LinkedList<RNode>();
|
||||||
for (var node: all()) {
|
for (var node: all()) {
|
||||||
var responseNode = node.toResponseObject();
|
response.add(detailsExtractor.extract(node, details));
|
||||||
|
|
||||||
for (var detail: details) {
|
|
||||||
// TODO...
|
|
||||||
}
|
|
||||||
|
|
||||||
response.add(responseNode);
|
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,14 +6,13 @@ import org.springframework.stereotype.Service;
|
|||||||
import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException;
|
import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException;
|
||||||
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
|
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
|
||||||
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
import ru.dragonestia.picker.model.Room;
|
import ru.dragonestia.picker.model.Room;
|
||||||
import ru.dragonestia.picker.model.Node;
|
import ru.dragonestia.picker.model.Node;
|
||||||
import ru.dragonestia.picker.model.User;
|
import ru.dragonestia.picker.model.User;
|
||||||
import ru.dragonestia.picker.repository.RoomRepository;
|
import ru.dragonestia.picker.repository.RoomRepository;
|
||||||
import ru.dragonestia.picker.repository.UserRepository;
|
|
||||||
import ru.dragonestia.picker.service.RoomService;
|
import ru.dragonestia.picker.service.RoomService;
|
||||||
|
import ru.dragonestia.picker.util.DetailsExtractor;
|
||||||
import ru.dragonestia.picker.util.NamingValidator;
|
import ru.dragonestia.picker.util.NamingValidator;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -27,7 +26,7 @@ import java.util.Set;
|
|||||||
public class RoomServiceImpl implements RoomService {
|
public class RoomServiceImpl implements RoomService {
|
||||||
|
|
||||||
private final RoomRepository roomRepository;
|
private final RoomRepository roomRepository;
|
||||||
private final UserRepository userRepository;
|
private final DetailsExtractor detailsExtractor;
|
||||||
private final NamingValidator namingValidator;
|
private final NamingValidator namingValidator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,16 +54,7 @@ public class RoomServiceImpl implements RoomService {
|
|||||||
public List<RRoom.Short> getAllRoomsWithDetailsResponse(Node node, Set<RoomDetails> details) {
|
public List<RRoom.Short> getAllRoomsWithDetailsResponse(Node node, Set<RoomDetails> details) {
|
||||||
var response = new LinkedList<RRoom.Short>();
|
var response = new LinkedList<RRoom.Short>();
|
||||||
for (var room: all(node)) {
|
for (var room: all(node)) {
|
||||||
var responseRoom = room.toShortResponseObject();
|
response.add(detailsExtractor.extract(room, details));
|
||||||
|
|
||||||
for (var detail: details) {
|
|
||||||
if (detail == RoomDetails.COUNT_USERS) {
|
|
||||||
var users = Integer.toString(userRepository.usersOf(room).size());
|
|
||||||
responseRoom.details().put(RoomDetails.COUNT_USERS, users);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.add(responseRoom);
|
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,15 @@ package ru.dragonestia.picker.service.impl;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||||
import ru.dragonestia.picker.model.Room;
|
import ru.dragonestia.picker.model.Room;
|
||||||
import ru.dragonestia.picker.model.User;
|
import ru.dragonestia.picker.model.User;
|
||||||
import ru.dragonestia.picker.repository.UserRepository;
|
import ru.dragonestia.picker.repository.UserRepository;
|
||||||
import ru.dragonestia.picker.service.UserService;
|
import ru.dragonestia.picker.service.UserService;
|
||||||
|
import ru.dragonestia.picker.util.DetailsExtractor;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -17,6 +20,7 @@ import java.util.function.Function;
|
|||||||
public class UserServiceImpl implements UserService {
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
private final DetailsExtractor detailsExtractor;
|
||||||
private final Map<UserDetails, Function<User, String>> detailsMap = new HashMap<>();
|
private final Map<UserDetails, Function<User, String>> detailsMap = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,6 +28,15 @@ public class UserServiceImpl implements UserService {
|
|||||||
return userRepository.findAllLinkedUserRooms(user);
|
return userRepository.findAllLinkedUserRooms(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RRoom.Short> getUserRoomsWithDetails(User user, Set<RoomDetails> details) {
|
||||||
|
var result = new LinkedList<RRoom.Short>();
|
||||||
|
for (var room: getUserRooms(user)) {
|
||||||
|
result.add(detailsExtractor.extract(room, details));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int linkUsersWithRoom(Room room, Collection<User> users, boolean force) {
|
public int linkUsersWithRoom(Room room, Collection<User> users, boolean force) {
|
||||||
userRepository.linkWithRoom(room, users, force);
|
userRepository.linkWithRoom(room, users, force);
|
||||||
@ -44,32 +57,18 @@ public class UserServiceImpl implements UserService {
|
|||||||
public List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details) {
|
public List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details) {
|
||||||
var users = new LinkedList<RUser>();
|
var users = new LinkedList<RUser>();
|
||||||
for (var user: getRoomUsers(room)) {
|
for (var user: getRoomUsers(room)) {
|
||||||
var responseUser = user.toResponseObject();
|
users.add(detailsExtractor.extract(user, details));
|
||||||
|
|
||||||
for (var detail: details) {
|
|
||||||
if (detail == UserDetails.COUNT_ROOMS) {
|
|
||||||
responseUser.putDetail(UserDetails.COUNT_ROOMS, Integer.toString(getUserRooms(user).size()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
users.add(responseUser);
|
|
||||||
}
|
}
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RUser> searchUsers(String input, Set<UserDetails> details) {
|
public List<RUser> searchUsers(String input, Set<UserDetails> details) {
|
||||||
return userRepository.search(input).stream()
|
return userRepository.search(input).stream().map(user -> detailsExtractor.extract(user, details)).toList();
|
||||||
.map(user -> {
|
}
|
||||||
var responseUser = user.toResponseObject();
|
|
||||||
|
|
||||||
for (var detail: details) {
|
@Override
|
||||||
if (detail == UserDetails.COUNT_ROOMS) {
|
public RUser getUserDetails(String userId, Set<UserDetails> details) {
|
||||||
responseUser.putDetail(UserDetails.COUNT_ROOMS, Integer.toString(getUserRooms(user).size()));
|
return detailsExtractor.extract(new User(userId), details);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseUser;
|
|
||||||
}).toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,62 @@
|
|||||||
|
package ru.dragonestia.picker.util;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.NodeDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RNode;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
|
import ru.dragonestia.picker.model.Node;
|
||||||
|
import ru.dragonestia.picker.model.Room;
|
||||||
|
import ru.dragonestia.picker.model.User;
|
||||||
|
import ru.dragonestia.picker.repository.NodeRepository;
|
||||||
|
import ru.dragonestia.picker.repository.RoomRepository;
|
||||||
|
import ru.dragonestia.picker.repository.UserRepository;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Component
|
||||||
|
public class DetailsExtractor {
|
||||||
|
|
||||||
|
private final NodeRepository nodeRepository;
|
||||||
|
private final RoomRepository roomRepository;
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
public RNode extract(Node node, Set<NodeDetails> details) {
|
||||||
|
var response = node.toResponseObject();
|
||||||
|
|
||||||
|
for (var detail: details) {
|
||||||
|
// TODO...
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RRoom.Short extract(Room room, Set<RoomDetails> details) {
|
||||||
|
var response = room.toShortResponseObject();
|
||||||
|
|
||||||
|
for (var detail: details) {
|
||||||
|
if (detail == RoomDetails.COUNT_USERS) {
|
||||||
|
var users = Integer.toString(userRepository.usersOf(room).size());
|
||||||
|
response.details().put(RoomDetails.COUNT_USERS, users);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RUser extract(User user, Set<UserDetails> details) {
|
||||||
|
var response = user.toResponseObject();
|
||||||
|
|
||||||
|
for (var detail: details) {
|
||||||
|
if (detail == UserDetails.COUNT_ROOMS) {
|
||||||
|
response.putDetail(UserDetails.COUNT_ROOMS, Integer.toString(userRepository.findAllLinkedUserRooms(user).size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
package ru.dragonestia.picker.util;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.NodeDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DetailsParser {
|
||||||
|
|
||||||
|
public Set<NodeDetails> parseNodeDetails(String detailsSeq) {
|
||||||
|
var details = new HashSet<NodeDetails>();
|
||||||
|
for (var detailStr: detailsSeq.split(",")) {
|
||||||
|
try {
|
||||||
|
details.add(NodeDetails.valueOf(detailStr.toUpperCase()));
|
||||||
|
} catch (IllegalArgumentException ignore) {}
|
||||||
|
}
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<RoomDetails> parseRoomDetails(String detailsSeq) {
|
||||||
|
var details = new HashSet<RoomDetails>();
|
||||||
|
for (var detailStr: detailsSeq.split(",")) {
|
||||||
|
try {
|
||||||
|
details.add(RoomDetails.valueOf(detailStr.toUpperCase()));
|
||||||
|
} catch (IllegalArgumentException ignore) {}
|
||||||
|
}
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<UserDetails> parseUserDetails(String detailsSeq) {
|
||||||
|
var details = new HashSet<UserDetails>();
|
||||||
|
for (var detailStr: detailsSeq.split(",")) {
|
||||||
|
try {
|
||||||
|
details.add(UserDetails.valueOf(detailStr.toUpperCase()));
|
||||||
|
} catch (IllegalArgumentException ignore) {}
|
||||||
|
}
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package ru.dragonestia.picker.cp.component;
|
package ru.dragonestia.picker.cp.component;
|
||||||
|
|
||||||
|
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.ColumnTextAlign;
|
||||||
import com.vaadin.flow.component.grid.Grid;
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
import com.vaadin.flow.component.html.Span;
|
import com.vaadin.flow.component.html.Span;
|
||||||
@ -32,10 +34,19 @@ public class UserList extends VerticalLayout {
|
|||||||
grid.addColumn(RUser::getId).setHeader("User Identifier").setFooter(totalUsers);
|
grid.addColumn(RUser::getId).setHeader("User Identifier").setFooter(totalUsers);
|
||||||
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms")
|
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms")
|
||||||
.setFooter(occupancy);
|
.setFooter(occupancy);
|
||||||
grid.addComponentColumn(user -> new Span("buttons")).setHeader("Manage"); // TODO
|
grid.addComponentColumn(this::createManageButton).setHeader("Manage");
|
||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Button createManageButton(RUser user) {
|
||||||
|
var button = new Button("Details");
|
||||||
|
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
button.addClickListener(e -> {
|
||||||
|
getUI().ifPresent(ui -> ui.navigate("/users/" + user.getId()));
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
public void update(List<RUser> users) {
|
public void update(List<RUser> users) {
|
||||||
cachedUsers = users;
|
cachedUsers = users;
|
||||||
usersGrid.setItems(users);
|
usersGrid.setItems(users);
|
||||||
|
|||||||
@ -1,17 +1,29 @@
|
|||||||
package ru.dragonestia.picker.cp.page;
|
package ru.dragonestia.picker.cp.page;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
import com.vaadin.flow.component.html.H1;
|
import com.vaadin.flow.component.html.H1;
|
||||||
import com.vaadin.flow.component.html.Paragraph;
|
import com.vaadin.flow.component.html.Paragraph;
|
||||||
|
import com.vaadin.flow.component.notification.Notification;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
import com.vaadin.flow.router.*;
|
import com.vaadin.flow.router.*;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
@Route(value = "/", layout = MainLayout.class)
|
@Route(value = "/", layout = MainLayout.class)
|
||||||
public class HomePage extends VerticalLayout {
|
public class HomePage extends VerticalLayout {
|
||||||
|
|
||||||
public HomePage() {
|
public HomePage() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
add(new H1("Hello world!"));
|
var field = new TextField("Some field");
|
||||||
add(new Paragraph("Hello world!"));
|
field.setRequired(true);
|
||||||
|
add(field);
|
||||||
|
|
||||||
|
var button = new Button("Click me", e -> {
|
||||||
|
Notification.show(field.isInvalid() + "");
|
||||||
|
});
|
||||||
|
|
||||||
|
add(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,74 @@
|
|||||||
|
package ru.dragonestia.picker.cp.page;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
|
import com.vaadin.flow.component.html.H2;
|
||||||
|
import com.vaadin.flow.component.html.H3;
|
||||||
|
import com.vaadin.flow.component.html.Span;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.router.BeforeEnterEvent;
|
||||||
|
import com.vaadin.flow.router.BeforeEnterObserver;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
|
import com.vaadin.flow.router.Route;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||||
|
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
|
import ru.dragonestia.picker.cp.util.RouteParamsExtractor;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@PageTitle("User details")
|
||||||
|
@Route(value = "/users/:userId", layout = MainLayout.class)
|
||||||
|
public class UserDetailsPage extends VerticalLayout implements BeforeEnterObserver {
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
private final RouteParamsExtractor paramsExtractor;
|
||||||
|
private RUser user;
|
||||||
|
private Grid<RRoom.Short> gridRooms;
|
||||||
|
private List<RRoom.Short> cachedRooms = new LinkedList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeEnter(BeforeEnterEvent event) {
|
||||||
|
user = paramsExtractor.extractUserId(event);
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
add(new H2("User '%s'".formatted(user.getId())));
|
||||||
|
add(new H3("Linked with rooms"));
|
||||||
|
add(gridRooms = createGrid());
|
||||||
|
|
||||||
|
update(userRepository.getLinkedRoomsWithUsers(user, RoomRepository.ALL_DETAILS));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Grid<RRoom.Short> createGrid() {
|
||||||
|
var grid = new Grid<RRoom.Short>();
|
||||||
|
|
||||||
|
grid.addColumn(RRoom.Short::id).setHeader("Room identifier");
|
||||||
|
|
||||||
|
grid.addColumn(RRoom.Short::nodeId).setHeader("Node identifier");
|
||||||
|
|
||||||
|
grid.addColumn(room -> room.details().get(RoomDetails.COUNT_USERS)).setHeader("Users");
|
||||||
|
|
||||||
|
grid.addComponentColumn(room -> {
|
||||||
|
var button = new Button("Details");
|
||||||
|
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
button.addClickListener(event -> {
|
||||||
|
getUI().ifPresent(ui -> ui.navigate("/nodes/%s/rooms/%s".formatted(room.nodeId(), room.id())));
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}).setHeader("Other");
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(List<RRoom.Short> rooms) {
|
||||||
|
gridRooms.setItems(cachedRooms = rooms);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package ru.dragonestia.picker.cp.page;
|
package ru.dragonestia.picker.cp.page;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.Unit;
|
import com.vaadin.flow.component.Unit;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
import com.vaadin.flow.component.button.ButtonVariant;
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
@ -49,6 +50,7 @@ public class UserSearchPage extends VerticalLayout {
|
|||||||
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
button.getStyle().set("color", "#FFFFFF");
|
button.getStyle().set("color", "#FFFFFF");
|
||||||
button.addClickListener(event -> search(fieldUsername.getValue().trim()));
|
button.addClickListener(event -> search(fieldUsername.getValue().trim()));
|
||||||
|
button.addClickShortcut(Key.ENTER);
|
||||||
|
|
||||||
field.setSuffixComponent(button);
|
field.setSuffixComponent(button);
|
||||||
return field;
|
return field;
|
||||||
@ -62,7 +64,14 @@ public class UserSearchPage extends VerticalLayout {
|
|||||||
|
|
||||||
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms");
|
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms");
|
||||||
|
|
||||||
grid.addComponentColumn(user -> new Span("buttons")).setHeader("Manage"); // TODO
|
grid.addComponentColumn(user -> {
|
||||||
|
var button = new Button("Details");
|
||||||
|
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
button.addClickListener(event -> {
|
||||||
|
getUI().ifPresent(ui -> ui.navigate("/users/" + user.getId()));
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}).setHeader("Manage");
|
||||||
|
|
||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,16 +7,17 @@ import org.springframework.http.HttpMethod;
|
|||||||
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
||||||
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
import ru.dragonestia.picker.api.exception.RoomAreFullException;
|
||||||
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
||||||
|
import ru.dragonestia.picker.api.repository.details.RoomDetails;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.LinkedRoomsWithUserResponse;
|
||||||
import ru.dragonestia.picker.api.repository.response.SearchUserResponse;
|
import ru.dragonestia.picker.api.repository.response.SearchUserResponse;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.UserDetailsResponse;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||||
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
import ru.dragonestia.picker.api.repository.details.UserDetails;
|
||||||
import ru.dragonestia.picker.api.repository.response.RoomUserListResponse;
|
import ru.dragonestia.picker.api.repository.response.RoomUserListResponse;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -68,4 +69,28 @@ public class UserRepositoryImpl implements UserRepository {
|
|||||||
params.put("input", input);
|
params.put("input", input);
|
||||||
}).users();
|
}).users();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RUser find(String userId, Set<UserDetails> details) {
|
||||||
|
return rest.query("/users/" + userId,
|
||||||
|
HttpMethod.GET,
|
||||||
|
UserDetailsResponse.class,
|
||||||
|
params -> {
|
||||||
|
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||||
|
|
||||||
|
params.put("requiredDetails", detailsStr);
|
||||||
|
}).user();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RRoom.Short> getLinkedRoomsWithUsers(RUser user, Set<RoomDetails> details) {
|
||||||
|
return rest.query("/users/" + user.getId() + "/rooms",
|
||||||
|
HttpMethod.GET,
|
||||||
|
LinkedRoomsWithUserResponse.class,
|
||||||
|
params -> {
|
||||||
|
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||||
|
|
||||||
|
params.put("requiredDetails", detailsStr);
|
||||||
|
}).rooms(); // TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,12 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
|
||||||
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
|
||||||
|
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RNode;
|
import ru.dragonestia.picker.api.repository.response.type.RNode;
|
||||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||||
import ru.dragonestia.picker.api.repository.NodeRepository;
|
import ru.dragonestia.picker.api.repository.NodeRepository;
|
||||||
import ru.dragonestia.picker.api.repository.RoomRepository;
|
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||||
|
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -16,6 +18,7 @@ public class RouteParamsExtractor {
|
|||||||
|
|
||||||
private final NodeRepository nodeRepository;
|
private final NodeRepository nodeRepository;
|
||||||
private final RoomRepository roomRepository;
|
private final RoomRepository roomRepository;
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
public RNode extractNodeId(BeforeEnterEvent e) throws NodeNotFoundException {
|
public RNode extractNodeId(BeforeEnterEvent e) throws NodeNotFoundException {
|
||||||
var nodeId = e.getRouteParameters().get("nodeId").orElseThrow(() -> new NodeNotFoundException("null"));
|
var nodeId = e.getRouteParameters().get("nodeId").orElseThrow(() -> new NodeNotFoundException("null"));
|
||||||
@ -26,4 +29,9 @@ public class RouteParamsExtractor {
|
|||||||
var roomId = e.getRouteParameters().get("roomId").orElseThrow(() -> new NodeNotFoundException("null"));
|
var roomId = e.getRouteParameters().get("roomId").orElseThrow(() -> new NodeNotFoundException("null"));
|
||||||
return roomRepository.find(node, roomId).orElseThrow(() -> new NodeNotFoundException(roomId));
|
return roomRepository.find(node, roomId).orElseThrow(() -> new NodeNotFoundException(roomId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RUser extractUserId(BeforeEnterEvent e) {
|
||||||
|
var userId = e.getRouteParameters().get("userId").orElseThrow(RuntimeException::new);
|
||||||
|
return userRepository.find(userId, UserRepository.ALL_DETAILS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user