diff --git a/api/src/main/java/ru/dragonestia/picker/api/repository/UserRepository.java b/api/src/main/java/ru/dragonestia/picker/api/repository/UserRepository.java index 28177d8..b5bfeee 100644 --- a/api/src/main/java/ru/dragonestia/picker/api/repository/UserRepository.java +++ b/api/src/main/java/ru/dragonestia/picker/api/repository/UserRepository.java @@ -3,12 +3,14 @@ package ru.dragonestia.picker.api.repository; 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.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.details.UserDetails; import java.util.Collection; import java.util.List; +import java.util.Optional; import java.util.Set; public interface UserRepository { @@ -26,4 +28,8 @@ public interface UserRepository { List all(RRoom room, Set details) throws NodeNotFoundException, RoomNotFoundException; List search(String input, Set details); + + RUser find(String userId, Set details); + + List getLinkedRoomsWithUsers(RUser user, Set roomDetails); } diff --git a/api/src/main/java/ru/dragonestia/picker/api/repository/response/LinkedRoomsWithUserResponse.java b/api/src/main/java/ru/dragonestia/picker/api/repository/response/LinkedRoomsWithUserResponse.java new file mode 100644 index 0000000..13e98f0 --- /dev/null +++ b/api/src/main/java/ru/dragonestia/picker/api/repository/response/LinkedRoomsWithUserResponse.java @@ -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 rooms) {} diff --git a/api/src/main/java/ru/dragonestia/picker/api/repository/response/UserDetailsResponse.java b/api/src/main/java/ru/dragonestia/picker/api/repository/response/UserDetailsResponse.java new file mode 100644 index 0000000..2d3a241 --- /dev/null +++ b/api/src/main/java/ru/dragonestia/picker/api/repository/response/UserDetailsResponse.java @@ -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) {} diff --git a/api/src/main/java/ru/dragonestia/picker/api/repository/response/type/RRoom.java b/api/src/main/java/ru/dragonestia/picker/api/repository/response/type/RRoom.java index 1e861d8..c4f88c6 100644 --- a/api/src/main/java/ru/dragonestia/picker/api/repository/response/type/RRoom.java +++ b/api/src/main/java/ru/dragonestia/picker/api/repository/response/type/RRoom.java @@ -87,5 +87,5 @@ public class RRoom { return false; } - public record Short(String id, int slots, boolean locked, Map details) {} + public record Short(String id, String nodeId, int slots, boolean locked, Map details) {} } diff --git a/app/src/main/java/ru/dragonestia/picker/controller/UserController.java b/app/src/main/java/ru/dragonestia/picker/controller/UserController.java index e903998..9b6e45d 100644 --- a/app/src/main/java/ru/dragonestia/picker/controller/UserController.java +++ b/app/src/main/java/ru/dragonestia/picker/controller/UserController.java @@ -1,16 +1,17 @@ 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 org.springframework.web.bind.annotation.*; +import ru.dragonestia.picker.api.repository.response.LinkedRoomsWithUserResponse; 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.util.DetailsParser; import ru.dragonestia.picker.util.NamingValidator; -import java.util.HashSet; import java.util.List; @RequiredArgsConstructor @@ -19,6 +20,7 @@ import java.util.List; public class UserController { private final UserService userService; + private final DetailsParser detailsParser; private final NamingValidator namingValidator; @GetMapping("/search") @@ -29,13 +31,28 @@ public class UserController { return new SearchUserResponse(List.of()); } - var details = new HashSet(); - for (var detailStr: detailsSeq.split(",")) { - try { - details.add(UserDetails.valueOf(detailStr.toUpperCase())); - } catch (IllegalArgumentException ignore) {} + return new SearchUserResponse(userService.searchUsers(input, detailsParser.parseUserDetails(detailsSeq))); + } + + @GetMapping("/{userId}") + 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))); } } diff --git a/app/src/main/java/ru/dragonestia/picker/model/Room.java b/app/src/main/java/ru/dragonestia/picker/model/Room.java index 5937cf9..5f6da44 100644 --- a/app/src/main/java/ru/dragonestia/picker/model/Room.java +++ b/app/src/main/java/ru/dragonestia/picker/model/Room.java @@ -54,6 +54,6 @@ public class Room { } 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<>()); } } diff --git a/app/src/main/java/ru/dragonestia/picker/repository/UserRepository.java b/app/src/main/java/ru/dragonestia/picker/repository/UserRepository.java index 5564f29..65ac8ba 100644 --- a/app/src/main/java/ru/dragonestia/picker/repository/UserRepository.java +++ b/app/src/main/java/ru/dragonestia/picker/repository/UserRepository.java @@ -1,7 +1,6 @@ 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; diff --git a/app/src/main/java/ru/dragonestia/picker/service/UserService.java b/app/src/main/java/ru/dragonestia/picker/service/UserService.java index b3ef7af..a9a65e3 100644 --- a/app/src/main/java/ru/dragonestia/picker/service/UserService.java +++ b/app/src/main/java/ru/dragonestia/picker/service/UserService.java @@ -1,6 +1,8 @@ package ru.dragonestia.picker.service; 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.details.UserDetails; import ru.dragonestia.picker.model.Room; @@ -14,6 +16,8 @@ public interface UserService { List getUserRooms(User user); + List getUserRoomsWithDetails(User user, Set details); + int linkUsersWithRoom(Room room, Collection users, boolean force) throws RoomAreFullException; void unlinkUsersFromRoom(Room room, Collection users); @@ -23,4 +27,6 @@ public interface UserService { List getRoomUsersWithDetailsResponse(Room room, Set details); List searchUsers(String input, Set details); + + RUser getUserDetails(String userId, Set details); } diff --git a/app/src/main/java/ru/dragonestia/picker/service/impl/NodeServiceImpl.java b/app/src/main/java/ru/dragonestia/picker/service/impl/NodeServiceImpl.java index a4f181c..3d4c9ac 100644 --- a/app/src/main/java/ru/dragonestia/picker/service/impl/NodeServiceImpl.java +++ b/app/src/main/java/ru/dragonestia/picker/service/impl/NodeServiceImpl.java @@ -9,6 +9,7 @@ import ru.dragonestia.picker.api.repository.response.type.RNode; import ru.dragonestia.picker.model.Node; import ru.dragonestia.picker.repository.NodeRepository; import ru.dragonestia.picker.service.NodeService; +import ru.dragonestia.picker.util.DetailsExtractor; import ru.dragonestia.picker.util.NamingValidator; import java.util.LinkedList; @@ -21,6 +22,7 @@ import java.util.Set; public class NodeServiceImpl implements NodeService { private final NodeRepository nodeRepository; + private final DetailsExtractor detailsExtractor; private final NamingValidator namingValidator; @Override @@ -43,13 +45,7 @@ public class NodeServiceImpl implements NodeService { public List getAllNodesWithDetailsResponse(Set details) { var response = new LinkedList(); for (var node: all()) { - var responseNode = node.toResponseObject(); - - for (var detail: details) { - // TODO... - } - - response.add(responseNode); + response.add(detailsExtractor.extract(node, details)); } return response; } diff --git a/app/src/main/java/ru/dragonestia/picker/service/impl/RoomServiceImpl.java b/app/src/main/java/ru/dragonestia/picker/service/impl/RoomServiceImpl.java index 8151353..05a071b 100644 --- a/app/src/main/java/ru/dragonestia/picker/service/impl/RoomServiceImpl.java +++ b/app/src/main/java/ru/dragonestia/picker/service/impl/RoomServiceImpl.java @@ -6,14 +6,13 @@ import org.springframework.stereotype.Service; import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException; import ru.dragonestia.picker.api.exception.RoomAlreadyExistException; 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.model.Room; import ru.dragonestia.picker.model.Node; import ru.dragonestia.picker.model.User; import ru.dragonestia.picker.repository.RoomRepository; -import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.service.RoomService; +import ru.dragonestia.picker.util.DetailsExtractor; import ru.dragonestia.picker.util.NamingValidator; import java.util.LinkedList; @@ -27,7 +26,7 @@ import java.util.Set; public class RoomServiceImpl implements RoomService { private final RoomRepository roomRepository; - private final UserRepository userRepository; + private final DetailsExtractor detailsExtractor; private final NamingValidator namingValidator; @Override @@ -55,16 +54,7 @@ public class RoomServiceImpl implements RoomService { public List getAllRoomsWithDetailsResponse(Node node, Set details) { var response = new LinkedList(); for (var room: all(node)) { - var responseRoom = room.toShortResponseObject(); - - 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); + response.add(detailsExtractor.extract(room, details)); } return response; } diff --git a/app/src/main/java/ru/dragonestia/picker/service/impl/UserServiceImpl.java b/app/src/main/java/ru/dragonestia/picker/service/impl/UserServiceImpl.java index d4a4b4c..ed75a3d 100644 --- a/app/src/main/java/ru/dragonestia/picker/service/impl/UserServiceImpl.java +++ b/app/src/main/java/ru/dragonestia/picker/service/impl/UserServiceImpl.java @@ -2,12 +2,15 @@ package ru.dragonestia.picker.service.impl; import lombok.RequiredArgsConstructor; 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.details.UserDetails; import ru.dragonestia.picker.model.Room; import ru.dragonestia.picker.model.User; import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.service.UserService; +import ru.dragonestia.picker.util.DetailsExtractor; import java.util.*; import java.util.function.Function; @@ -17,6 +20,7 @@ import java.util.function.Function; public class UserServiceImpl implements UserService { private final UserRepository userRepository; + private final DetailsExtractor detailsExtractor; private final Map> detailsMap = new HashMap<>(); @Override @@ -24,6 +28,15 @@ public class UserServiceImpl implements UserService { return userRepository.findAllLinkedUserRooms(user); } + @Override + public List getUserRoomsWithDetails(User user, Set details) { + var result = new LinkedList(); + for (var room: getUserRooms(user)) { + result.add(detailsExtractor.extract(room, details)); + } + return result; + } + @Override public int linkUsersWithRoom(Room room, Collection users, boolean force) { userRepository.linkWithRoom(room, users, force); @@ -44,32 +57,18 @@ public class UserServiceImpl implements UserService { public List getRoomUsersWithDetailsResponse(Room room, Set details) { var users = new LinkedList(); for (var user: getRoomUsers(room)) { - var responseUser = user.toResponseObject(); - - for (var detail: details) { - if (detail == UserDetails.COUNT_ROOMS) { - responseUser.putDetail(UserDetails.COUNT_ROOMS, Integer.toString(getUserRooms(user).size())); - } - } - - users.add(responseUser); + users.add(detailsExtractor.extract(user, details)); } return users; } @Override public List searchUsers(String input, Set details) { - return userRepository.search(input).stream() - .map(user -> { - var responseUser = user.toResponseObject(); + return userRepository.search(input).stream().map(user -> detailsExtractor.extract(user, details)).toList(); + } - for (var detail: details) { - if (detail == UserDetails.COUNT_ROOMS) { - responseUser.putDetail(UserDetails.COUNT_ROOMS, Integer.toString(getUserRooms(user).size())); - } - } - - return responseUser; - }).toList(); + @Override + public RUser getUserDetails(String userId, Set details) { + return detailsExtractor.extract(new User(userId), details); } } diff --git a/app/src/main/java/ru/dragonestia/picker/util/DetailsExtractor.java b/app/src/main/java/ru/dragonestia/picker/util/DetailsExtractor.java new file mode 100644 index 0000000..7e720a8 --- /dev/null +++ b/app/src/main/java/ru/dragonestia/picker/util/DetailsExtractor.java @@ -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 details) { + var response = node.toResponseObject(); + + for (var detail: details) { + // TODO... + } + + return response; + } + + public RRoom.Short extract(Room room, Set 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 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; + } +} diff --git a/app/src/main/java/ru/dragonestia/picker/util/DetailsParser.java b/app/src/main/java/ru/dragonestia/picker/util/DetailsParser.java new file mode 100644 index 0000000..f6ea12b --- /dev/null +++ b/app/src/main/java/ru/dragonestia/picker/util/DetailsParser.java @@ -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 parseNodeDetails(String detailsSeq) { + var details = new HashSet(); + for (var detailStr: detailsSeq.split(",")) { + try { + details.add(NodeDetails.valueOf(detailStr.toUpperCase())); + } catch (IllegalArgumentException ignore) {} + } + return details; + } + + public Set parseRoomDetails(String detailsSeq) { + var details = new HashSet(); + for (var detailStr: detailsSeq.split(",")) { + try { + details.add(RoomDetails.valueOf(detailStr.toUpperCase())); + } catch (IllegalArgumentException ignore) {} + } + return details; + } + + public Set parseUserDetails(String detailsSeq) { + var details = new HashSet(); + for (var detailStr: detailsSeq.split(",")) { + try { + details.add(UserDetails.valueOf(detailStr.toUpperCase())); + } catch (IllegalArgumentException ignore) {} + } + return details; + } +} diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/component/UserList.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/component/UserList.java index 27762ae..9c207bc 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/component/UserList.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/component/UserList.java @@ -1,5 +1,7 @@ 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.Grid; 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(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms") .setFooter(occupancy); - grid.addComponentColumn(user -> new Span("buttons")).setHeader("Manage"); // TODO + grid.addComponentColumn(this::createManageButton).setHeader("Manage"); 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 users) { cachedUsers = users; usersGrid.setItems(users); diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/HomePage.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/HomePage.java index 9f6109f..1549a5a 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/HomePage.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/HomePage.java @@ -1,17 +1,29 @@ 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.Paragraph; +import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.*; +import java.awt.*; + @Route(value = "/", layout = MainLayout.class) public class HomePage extends VerticalLayout { public HomePage() { super(); - add(new H1("Hello world!")); - add(new Paragraph("Hello world!")); + var field = new TextField("Some field"); + field.setRequired(true); + add(field); + + var button = new Button("Click me", e -> { + Notification.show(field.isInvalid() + ""); + }); + + add(button); } } diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserDetailsPage.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserDetailsPage.java new file mode 100644 index 0000000..c627e1c --- /dev/null +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserDetailsPage.java @@ -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 gridRooms; + private List 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 createGrid() { + var grid = new Grid(); + + 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 rooms) { + gridRooms.setItems(cachedRooms = rooms); + } +} diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserSearchPage.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserSearchPage.java index d4ecab6..5b4b6a1 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserSearchPage.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/UserSearchPage.java @@ -1,5 +1,6 @@ package ru.dragonestia.picker.cp.page; +import com.vaadin.flow.component.Key; import com.vaadin.flow.component.Unit; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; @@ -49,6 +50,7 @@ public class UserSearchPage extends VerticalLayout { button.addThemeVariants(ButtonVariant.LUMO_PRIMARY); button.getStyle().set("color", "#FFFFFF"); button.addClickListener(event -> search(fieldUsername.getValue().trim())); + button.addClickShortcut(Key.ENTER); field.setSuffixComponent(button); 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.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; } diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/UserRepositoryImpl.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/UserRepositoryImpl.java index a3e95f9..425d8a2 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/UserRepositoryImpl.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/UserRepositoryImpl.java @@ -7,16 +7,17 @@ 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.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.UserDetailsResponse; 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; import ru.dragonestia.picker.api.repository.details.UserDetails; import ru.dragonestia.picker.api.repository.response.RoomUserListResponse; -import java.util.Collection; -import java.util.List; -import java.util.Set; +import java.util.*; @Log4j2 @RequiredArgsConstructor @@ -68,4 +69,28 @@ public class UserRepositoryImpl implements UserRepository { params.put("input", input); }).users(); } + + @Override + public RUser find(String userId, Set 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 getLinkedRoomsWithUsers(RUser user, Set 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 + } } diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/util/RouteParamsExtractor.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/util/RouteParamsExtractor.java index 0d3cc55..b448ab9 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/util/RouteParamsExtractor.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/util/RouteParamsExtractor.java @@ -5,10 +5,12 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import ru.dragonestia.picker.api.exception.NodeNotFoundException; 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.RRoom; import ru.dragonestia.picker.api.repository.NodeRepository; import ru.dragonestia.picker.api.repository.RoomRepository; +import ru.dragonestia.picker.api.repository.response.type.RUser; @Component @RequiredArgsConstructor @@ -16,6 +18,7 @@ public class RouteParamsExtractor { private final NodeRepository nodeRepository; private final RoomRepository roomRepository; + private final UserRepository userRepository; public RNode extractNodeId(BeforeEnterEvent e) throws NodeNotFoundException { 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")); 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); + } }