From 4da58baa4604b79e755891fac5801f6f4cc1e7cb Mon Sep 17 00:00:00 2001 From: ScarletRedMan Date: Thu, 11 Jan 2024 13:33:21 +0700 Subject: [PATCH] Implemented link users with room --- .../picker/controller/UserRoomController.java | 25 ++++++++----- .../response/LinkUsersWithRoomResponse.java | 2 +- .../picker/service/UserService.java | 2 +- .../picker/service/impl/UserServiceImpl.java | 3 +- .../picker/cp/component/AddUsers.java | 16 +++++++- .../picker/cp/page/RoomDetailsPage.java | 37 ++++++++++++++++++- .../picker/cp/repository/UserRepository.java | 2 +- .../repository/impl/UserRepositoryImpl.java | 28 ++++++++++++-- .../response/LinkUsersWithRoomResponse.java | 3 ++ 9 files changed, 98 insertions(+), 20 deletions(-) create mode 100644 control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/response/LinkUsersWithRoomResponse.java diff --git a/app/src/main/java/ru/dragonestia/picker/controller/UserRoomController.java b/app/src/main/java/ru/dragonestia/picker/controller/UserRoomController.java index 579a09d..f06a3ff 100644 --- a/app/src/main/java/ru/dragonestia/picker/controller/UserRoomController.java +++ b/app/src/main/java/ru/dragonestia/picker/controller/UserRoomController.java @@ -52,7 +52,7 @@ public class UserRoomController { var temp = getNodeAndRoom(nodeId, roomId); room = temp.room(); } catch (Error error) { - return ResponseEntity.status(404).body(new LinkUsersWithRoomResponse(false, error.getMessage())); + return ResponseEntity.status(404).body(new LinkUsersWithRoomResponse(false, error.getMessage(), -1, -1)); } var list = new LinkedList(); @@ -63,12 +63,12 @@ public class UserRoomController { } try { - userService.linkUsersWithRoom(room, list, force); - } catch (Error error) { - return ResponseEntity.status(400).body(new LinkUsersWithRoomResponse(false, error.getMessage())); - } + int usedSlots = userService.linkUsersWithRoom(room, list, force); - return ResponseEntity.ok(new LinkUsersWithRoomResponse(true, "Success")); + return ResponseEntity.ok(new LinkUsersWithRoomResponse(true, "Success", usedSlots, room.getSlots().getSlots())); + } catch (Error error) { + return ResponseEntity.status(400).body(new LinkUsersWithRoomResponse(false, error.getMessage(), -1, -1)); + } } @DeleteMapping @@ -76,17 +76,24 @@ public class UserRoomController { @PathVariable(name = "roomId") String roomId, @RequestParam(name = "userIds") String userIds) { - Node node; Room room; try { var temp = getNodeAndRoom(nodeId, roomId); - node = temp.node(); room = temp.room(); + + var list = new LinkedList(); + for (var username: userIds.split(",")) { + if (!NamingValidator.validateUserId(username)) continue; + + list.add(new User(username)); + } + + userService.unlinkUsersFromRoom(room, list); } catch (Error error) { return ResponseEntity.notFound().build(); } - return null; + return ResponseEntity.ok().build(); } private record NodeAndRoom(Node node, Room room) {} diff --git a/app/src/main/java/ru/dragonestia/picker/controller/response/LinkUsersWithRoomResponse.java b/app/src/main/java/ru/dragonestia/picker/controller/response/LinkUsersWithRoomResponse.java index aa7093b..0508393 100644 --- a/app/src/main/java/ru/dragonestia/picker/controller/response/LinkUsersWithRoomResponse.java +++ b/app/src/main/java/ru/dragonestia/picker/controller/response/LinkUsersWithRoomResponse.java @@ -1,3 +1,3 @@ package ru.dragonestia.picker.controller.response; -public record LinkUsersWithRoomResponse(boolean success, String message) {} +public record LinkUsersWithRoomResponse(boolean success, String message, int usedSlots, int totalSlots) {} 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 3e6a8f3..682abb9 100644 --- a/app/src/main/java/ru/dragonestia/picker/service/UserService.java +++ b/app/src/main/java/ru/dragonestia/picker/service/UserService.java @@ -10,7 +10,7 @@ public interface UserService { List getUserRooms(User user); - void linkUsersWithRoom(Room room, Collection users, boolean force); + int linkUsersWithRoom(Room room, Collection users, boolean force); void unlinkUsersFromRoom(Room room, Collection users); 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 13057fc..6774bc5 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 @@ -22,8 +22,9 @@ public class UserServiceImpl implements UserService { } @Override - public void linkUsersWithRoom(Room room, Collection users, boolean force) { + public int linkUsersWithRoom(Room room, Collection users, boolean force) { userRepository.linkWithRoom(room, users, force); + return userRepository.usersOf(room).size(); } @Override diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/component/AddUsers.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/component/AddUsers.java index f20f325..6a12b1b 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/component/AddUsers.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/component/AddUsers.java @@ -9,24 +9,31 @@ import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.H2; import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.notification.NotificationVariant; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.textfield.TextField; import lombok.Getter; import ru.dragonestia.picker.cp.model.Room; import ru.dragonestia.picker.cp.model.User; +import java.util.Collection; import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Consumer; public class AddUsers extends Details { private final Room room; + private final BiConsumer, Boolean> onCommit; private final Checkbox ignoreSlots; private final VerticalLayout usersLayout; - public AddUsers(Room room) { + public AddUsers(Room room, BiConsumer, Boolean> onCommit) { super(new H2("Add users")); this.room = room; + this.onCommit = onCommit; usersLayout = new VerticalLayout(); add(addUserToTransacionButton()); @@ -69,7 +76,12 @@ public class AddUsers extends Details { } private void onClick() { - //TODO: save data + try { + onCommit.accept(readAllUsers(), ignoreSlots.getValue()); + } catch (Error error) { + Notification.show(error.getMessage(), 3000, Notification.Position.TOP_END) + .addThemeVariants(NotificationVariant.LUMO_ERROR); + } clear(); } diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/RoomDetailsPage.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/RoomDetailsPage.java index d539f9d..8a69751 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/page/RoomDetailsPage.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/page/RoomDetailsPage.java @@ -1,7 +1,6 @@ package ru.dragonestia.picker.cp.page; import com.vaadin.flow.component.Html; -import com.vaadin.flow.component.Text; import com.vaadin.flow.component.Unit; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.html.H2; @@ -23,10 +22,14 @@ import ru.dragonestia.picker.cp.component.NavPath; import ru.dragonestia.picker.cp.component.UserList; import ru.dragonestia.picker.cp.model.Room; import ru.dragonestia.picker.cp.model.Node; +import ru.dragonestia.picker.cp.model.User; import ru.dragonestia.picker.cp.repository.RoomRepository; import ru.dragonestia.picker.cp.repository.NodeRepository; import ru.dragonestia.picker.cp.repository.UserRepository; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + @PageTitle("Room details") @Route("/nodes/:nodeId/rooms/:roomId") public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserver { @@ -95,7 +98,7 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv add(new H2("Room details")); printRoomDetails(); add(new Hr()); - add(addUsers = new AddUsers(room)); + add(addUsers = new AddUsers(room, (users, ignoreLimitation) -> appendUsers(room, users, ignoreLimitation))); add(new Hr()); add(new H2("Users")); add(userList = new UserList(room, userRepository.all(room))); @@ -151,4 +154,34 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv Notification.show("Success", 3000, Notification.Position.TOP_END) .addThemeVariants(NotificationVariant.LUMO_SUCCESS); } + + private void appendUsers(Room room, Collection users, boolean ignoreLimitation) { + AtomicBoolean validationFail = new AtomicBoolean(false); + + var newUsers = users.stream() + .filter(user -> { + if (user.id().matches("^[aA-zZ\\d-.\\s:/@%?!~$)(+=_|;*]+$")) { + return true; + } + + validationFail.set(true); + return false; + }).toList(); + + userRepository.linkWithRoom(room, newUsers, ignoreLimitation); + userList.update(userRepository.all(room)); + + if (validationFail.get()) { + if (newUsers.isEmpty()) { + Notification.show("All users entered were added because they do not comply with the rule for writing the user identifier", 3000, Notification.Position.TOP_END) + .addThemeVariants(NotificationVariant.LUMO_ERROR); + } else { + Notification.show("Not all users entered were added because they do not comply with the rule for writing the user identifier", 3000, Notification.Position.TOP_END) + .addThemeVariants(NotificationVariant.LUMO_WARNING); + } + } else { + Notification.show("Success", 3000, Notification.Position.TOP_END) + .addThemeVariants(NotificationVariant.LUMO_SUCCESS); + } + } } diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/UserRepository.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/UserRepository.java index e326c22..f2bcdd2 100644 --- a/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/UserRepository.java +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/UserRepository.java @@ -8,7 +8,7 @@ import java.util.List; public interface UserRepository { - void linkWithRoom(Room room, Collection users); + void linkWithRoom(Room room, Collection users, boolean force); void unlinkFromRoom(Room room, Collection users); 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 1ced238..90a1e56 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 @@ -6,6 +6,7 @@ import lombok.extern.log4j.Log4j2; import ru.dragonestia.picker.cp.model.Room; import ru.dragonestia.picker.cp.model.User; import ru.dragonestia.picker.cp.repository.UserRepository; +import ru.dragonestia.picker.cp.repository.impl.response.LinkUsersWithRoomResponse; import ru.dragonestia.picker.cp.repository.impl.response.RoomUserListResponse; import java.net.URI; @@ -20,13 +21,34 @@ public class UserRepositoryImpl implements UserRepository { private final RestUtil rest; @Override - public void linkWithRoom(Room room, Collection users) { - // TODO + public void linkWithRoom(Room room, Collection users, boolean force) { + try { + var response = rest.post(URI.create("/nodes/%s/rooms/%s/users".formatted(room.getNodeId(), room.getId())), + LinkUsersWithRoomResponse.class, + params -> { + params.put("userIds", String.join(",", users.stream().map(User::id).toList())); + params.put("force", Boolean.toString(force)); + } + ); + + if (!response.success()) { + throw new Error(response.message()); + } + } catch (Exception ex) { + log.throwing(ex); + throw new Error("Internal error"); + } } @Override public void unlinkFromRoom(Room room, Collection users) { - // TODO + try { + rest.delete(URI.create("/nodes/%s/rooms/%s/users".formatted(room.getNodeId(), room.getId())), + params -> params.put("userIds", String.join(",", users.stream().map(User::id).toList()))); + } catch (Exception ex) { + log.throwing(ex); + throw new Error("Internal error"); + } } @Override diff --git a/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/response/LinkUsersWithRoomResponse.java b/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/response/LinkUsersWithRoomResponse.java new file mode 100644 index 0000000..04f19be --- /dev/null +++ b/control-panel/src/main/java/ru/dragonestia/picker/cp/repository/impl/response/LinkUsersWithRoomResponse.java @@ -0,0 +1,3 @@ +package ru.dragonestia.picker.cp.repository.impl.response; + +public record LinkUsersWithRoomResponse(boolean success, String message, int usedSlots, int totalSlots) {}