Implemented getting details for method 'repository.all()' if it required

This commit is contained in:
Andrey Terentev 2024-01-17 18:38:53 +07:00 committed by Andrey Terentev
parent bf8aa8c3ba
commit ecde48460b
49 changed files with 496 additions and 244 deletions

View File

@ -1,39 +0,0 @@
package ru.dragonestia.picker.api.model;
import ru.dragonestia.picker.api.model.type.PickingMode;
public class Node {
private String id;
private PickingMode mode;
private Node() {}
public Node(String id, PickingMode mode) {
this.id = id;
this.mode = mode;
}
public String getId() {
return id;
}
public PickingMode getMode() {
return mode;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (object == null) return false;
if (object instanceof Node other) {
return id.equals(other.id);
}
return false;
}
}

View File

@ -1,31 +0,0 @@
package ru.dragonestia.picker.api.model;
public class User {
private String id;
private User() {}
public User(String id) {
this.id = id;
}
public String getId() {
return id;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (object == null) return false;
if (object instanceof User other) {
return id.equals(other.id);
}
return false;
}
}

View File

@ -2,18 +2,26 @@ package ru.dragonestia.picker.api.repository;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.repository.details.NodeDetails;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface NodeRepository {
void register(Node node) throws InvalidNodeIdentifierException, NodeAlreadyExistException;
Set<NodeDetails> ALL_DETAILS = Set.of();
List<Node> all();
void register(RNode node) throws InvalidNodeIdentifierException, NodeAlreadyExistException;
Optional<Node> find(String nodeId);
default List<RNode> all() {
return all(Set.of());
}
List<RNode> all(Set<NodeDetails> details);
Optional<RNode> find(String nodeId);
void remove(String nodeId);
}

View File

@ -1,23 +1,31 @@
package ru.dragonestia.picker.api.repository;
import ru.dragonestia.picker.api.exception.*;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.repository.details.RoomDetails;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface RoomRepository {
void register(Room room) throws NodeNotFoundException, InvalidRoomIdentifierException, RoomAlreadyExistException;
Set<RoomDetails> ALL_DETAILS = Set.of(RoomDetails.COUNT_USERS);
void remove(Room room) throws NodeNotFoundException;
void register(RRoom room) throws NodeNotFoundException, InvalidRoomIdentifierException, RoomAlreadyExistException;
void remove(Node node, Room.Short room) throws NodeNotFoundException;
void remove(RRoom room) throws NodeNotFoundException;
List<Room.Short> all(Node node) throws NodeNotFoundException;
void remove(RNode node, RRoom.Short room) throws NodeNotFoundException;
Optional<Room> find(Node node, String roomId) throws NodeNotFoundException;
default List<RRoom.Short> all(RNode node) throws NodeNotFoundException {
return all(node, Set.of());
}
void lock(Room room, boolean value) throws NodeNotFoundException, RoomNotFoundException;
List<RRoom.Short> all(RNode node, Set<RoomDetails> details) throws NodeNotFoundException;
Optional<RRoom> find(RNode node, String roomId) throws NodeNotFoundException;
void lock(RRoom room, boolean value) throws NodeNotFoundException, RoomNotFoundException;
}

View File

@ -3,17 +3,25 @@ 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.model.Room;
import ru.dragonestia.picker.api.model.User;
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.Set;
public interface UserRepository {
void linkWithRoom(Room room, Collection<User> users, boolean force) throws NodeNotFoundException, RoomNotFoundException, RoomAreFullException;
Set<UserDetails> ALL_DETAILS = Set.of(UserDetails.COUNT_ROOMS);
void unlinkFromRoom(Room room, Collection<User> users) throws NodeNotFoundException, RoomNotFoundException;
void linkWithRoom(RRoom room, Collection<RUser> users, boolean force) throws NodeNotFoundException, RoomNotFoundException, RoomAreFullException;
List<User> all(Room room) throws NodeNotFoundException, RoomNotFoundException;
void unlinkFromRoom(RRoom room, Collection<RUser> users) throws NodeNotFoundException, RoomNotFoundException;
default List<RUser> all(RRoom room) throws NodeNotFoundException, RoomNotFoundException {
return all(room, Set.of());
}
List<RUser> all(RRoom room, Set<UserDetails> details) throws NodeNotFoundException, RoomNotFoundException;
}

View File

@ -0,0 +1,4 @@
package ru.dragonestia.picker.api.repository.details;
public enum NodeDetails {
}

View File

@ -0,0 +1,5 @@
package ru.dragonestia.picker.api.repository.details;
public enum RoomDetails {
COUNT_USERS
}

View File

@ -0,0 +1,5 @@
package ru.dragonestia.picker.api.repository.details;
public enum UserDetails {
COUNT_ROOMS
}

View File

@ -1,5 +1,5 @@
package ru.dragonestia.picker.api.repository.response;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.repository.response.type.RNode;
public record NodeDetailsResponse(Node node) {}
public record NodeDetailsResponse(RNode node) {}

View File

@ -1,7 +1,7 @@
package ru.dragonestia.picker.api.repository.response;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import java.util.List;
public record NodeListResponse(List<Node> nodes) {}
public record NodeListResponse(List<RNode> nodes) {}

View File

@ -1,5 +1,5 @@
package ru.dragonestia.picker.api.repository.response;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
public record RoomInfoResponse(Room room) {}
public record RoomInfoResponse(RRoom room) {}

View File

@ -1,7 +1,7 @@
package ru.dragonestia.picker.api.repository.response;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import java.util.List;
public record RoomListResponse(String node, List<Room.Short> rooms) {}
public record RoomListResponse(String node, List<RRoom.Short> rooms) {}

View File

@ -1,7 +1,7 @@
package ru.dragonestia.picker.api.repository.response;
import ru.dragonestia.picker.api.model.User;
import ru.dragonestia.picker.api.repository.response.type.RUser;
import java.util.List;
public record RoomUserListResponse(int slots, int usedSlots, List<User> users) {}
public record RoomUserListResponse(int slots, int usedSlots, List<RUser> users) {}

View File

@ -0,0 +1,57 @@
package ru.dragonestia.picker.api.repository.response.type;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.api.repository.details.NodeDetails;
import java.util.HashMap;
import java.util.Map;
public class RNode {
private String id;
private PickingMode mode;
private Map<NodeDetails, String> details;
private RNode() {}
public RNode(String id, PickingMode mode) {
this.id = id;
this.mode = mode;
this.details = new HashMap<>();
}
public String getId() {
return id;
}
public PickingMode getMode() {
return mode;
}
public void putDetail(NodeDetails detail, String value) {
details.put(detail, value);
}
public String getDetails(NodeDetails detail, String value) {
return details.get(detail);
}
public Map<NodeDetails, String> getDetails() {
return details;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (object == null) return false;
if (object instanceof RNode other) {
return id.equals(other.id);
}
return false;
}
}

View File

@ -1,8 +1,12 @@
package ru.dragonestia.picker.api.model;
package ru.dragonestia.picker.api.repository.response.type;
import ru.dragonestia.picker.api.repository.details.RoomDetails;
import java.beans.Transient;
import java.util.HashMap;
import java.util.Map;
public class Room {
public class RRoom {
public final static int INFINITE_SLOTS = -1;
@ -11,17 +15,19 @@ public class Room {
private int slots;
private String payload;
private boolean locked = false;
private Map<RoomDetails, String> details;
private Room() {}
private RRoom() {}
public Room(String id, String nodeId, int slots, String payload) {
public RRoom(String id, String nodeId, int slots, String payload) {
this.id = id;
this.nodeId = nodeId;
this.slots = slots;
this.payload = payload;
this.details = new HashMap<>();
}
public Room(String id, Node node, int limit, String payload) {
public RRoom(String id, RNode node, int limit, String payload) {
this(id, node.getId(), limit, payload);
}
@ -54,6 +60,18 @@ public class Room {
return slots == INFINITE_SLOTS;
}
public void putDetail(RoomDetails detail, String value) {
details.put(detail, value);
}
public String getDetail(RoomDetails detail) {
return details.get(detail);
}
public Map<RoomDetails, String> getDetails() {
return details;
}
@Override
public int hashCode() {
return id.hashCode();
@ -63,11 +81,11 @@ public class Room {
public boolean equals(Object object) {
if (object == this) return true;
if (object == null) return false;
if (object instanceof Room other) {
if (object instanceof RRoom other) {
return id.equals(other.id);
}
return false;
}
public record Short(String id, int slots, boolean locked) {}
public record Short(String id, int slots, boolean locked, Map<RoomDetails, String> details) {}
}

View File

@ -0,0 +1,50 @@
package ru.dragonestia.picker.api.repository.response.type;
import ru.dragonestia.picker.api.repository.details.UserDetails;
import java.util.HashMap;
import java.util.Map;
public class RUser {
private String id;
private Map<UserDetails, String> details = new HashMap<>();
private RUser() {}
public RUser(String id) {
this.id = id;
this.details = new HashMap<>();
}
public String getId() {
return id;
}
public void putDetail(UserDetails detail, String value) {
details.put(detail, value);
}
public String getDetail(UserDetails detail) {
return details.get(detail);
}
public Map<UserDetails, String> getDetails() {
return details;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (object == null) return false;
if (object instanceof RUser other) {
return id.equals(other.id);
}
return false;
}
}

View File

@ -1,4 +1,4 @@
package ru.dragonestia.picker.api.model.type;
package ru.dragonestia.picker.api.repository.response.type.type;
public enum PickingMode {
SEQUENTIAL_FILLING("Sequential filling"),

View File

@ -7,7 +7,7 @@ import org.springframework.context.annotation.Profile;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.interceptor.DebugInterceptor;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.Node;

View File

@ -4,7 +4,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.details.NodeDetails;
import ru.dragonestia.picker.api.repository.details.RoomDetails;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.NodeDetailsResponse;
import ru.dragonestia.picker.api.repository.response.NodeListResponse;
import ru.dragonestia.picker.model.Node;
@ -13,6 +15,7 @@ import ru.dragonestia.picker.service.RoomService;
import ru.dragonestia.picker.util.NamingValidator;
import java.util.Arrays;
import java.util.HashSet;
@RestController
@RequestMapping("/nodes")
@ -24,8 +27,15 @@ public class NodeController {
private final NamingValidator namingValidator;
@GetMapping
NodeListResponse allNodes() {
return new NodeListResponse(nodeService.all().stream().map(Node::toResponseObject).toList());
NodeListResponse allNodes(@RequestParam(name = "requiredDetails", required = false, defaultValue = "") String detailsSeq) {
var details = new HashSet<NodeDetails>();
for (var detailStr: detailsSeq.split(",")) {
try {
details.add(NodeDetails.valueOf(detailStr.toUpperCase()));
} catch (IllegalArgumentException ignore) {}
}
return new NodeListResponse(nodeService.getAllNodesWithDetailsResponse(details));
}
@PostMapping

View File

@ -6,6 +6,9 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
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.RoomInfoResponse;
import ru.dragonestia.picker.api.repository.response.RoomListResponse;
import ru.dragonestia.picker.model.Room;
@ -14,6 +17,8 @@ import ru.dragonestia.picker.service.RoomService;
import ru.dragonestia.picker.service.NodeService;
import ru.dragonestia.picker.util.NamingValidator;
import java.util.HashSet;
@Log4j2
@RestController
@RequestMapping("/nodes/{nodeId}/rooms")
@ -25,14 +30,19 @@ public class RoomController {
private final NamingValidator namingValidator;
@GetMapping
ResponseEntity<RoomListResponse> all(@PathVariable(name = "nodeId") String nodeId) {
ResponseEntity<RoomListResponse> all(@PathVariable(name = "nodeId") String nodeId,
@RequestParam(name = "requiredDetails", required = false, defaultValue = "") String detailsSeq) {
var details = new HashSet<RoomDetails>();
for (var detailStr: detailsSeq.split(",")) {
try {
details.add(RoomDetails.valueOf(detailStr.toUpperCase()));
} catch (IllegalArgumentException ignore) {}
}
return nodeService.find(nodeId)
.map(node -> ResponseEntity.ok(new RoomListResponse(nodeId,
roomService.all(node).stream()
.map(room -> new ru.dragonestia.picker.api.model.Room.Short(room.getId(), room.getSlots().getSlots(), room.isLocked()))
.toList()
))).orElseThrow(() -> new NodeNotFoundException(nodeId));
.map(node -> ResponseEntity.ok(new RoomListResponse(nodeId, roomService.getAllRoomsWithDetailsResponse(node, details))))
.orElseThrow(() -> new NodeNotFoundException(nodeId));
}
@PostMapping

View File

@ -5,17 +5,18 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
import ru.dragonestia.picker.api.repository.details.UserDetails;
import ru.dragonestia.picker.api.repository.response.LinkUsersWithRoomResponse;
import ru.dragonestia.picker.api.repository.response.RoomUserListResponse;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.Node;
import ru.dragonestia.picker.model.User;
import ru.dragonestia.picker.service.RoomService;
import ru.dragonestia.picker.service.NodeService;
import ru.dragonestia.picker.service.UserService;
import ru.dragonestia.picker.util.NamingValidator;
import java.util.Arrays;
import java.util.HashSet;
@RequiredArgsConstructor
@RestController
@ -29,11 +30,21 @@ public class UserRoomController {
@GetMapping
ResponseEntity<RoomUserListResponse> usersInsideRoom(@PathVariable(name = "nodeId") String nodeId,
@PathVariable(name = "roomId") String roomId) {
@PathVariable(name = "roomId") String roomId,
@RequestParam(name = "requiredDetails", required = false, defaultValue = "") String detailsSeq) {
var room = getNodeAndRoom(nodeId, roomId).room();
var users = userService.getRoomUsers(room);
return ResponseEntity.ok(new RoomUserListResponse(room.getSlots().getSlots(), users.size(), users.stream().map(User::toResponseObject).toList()));
var details = new HashSet<UserDetails>();
for (var detailStr: detailsSeq.split(",")) {
try {
details.add(UserDetails.valueOf(detailStr.toUpperCase()));
} catch (IllegalArgumentException ignore) {}
}
var users = userService.getRoomUsersWithDetailsResponse(room, details);
return ResponseEntity.ok(new RoomUserListResponse(room.getSlots().getSlots(), users.size(), users));
}
@PostMapping

View File

@ -1,7 +1,8 @@
package ru.dragonestia.picker.model;
import lombok.NonNull;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
public record Node(@NonNull String id, @NonNull PickingMode mode) {
@ -20,7 +21,7 @@ public record Node(@NonNull String id, @NonNull PickingMode mode) {
return false;
}
public ru.dragonestia.picker.api.model.Node toResponseObject() {
return new ru.dragonestia.picker.api.model.Node(id, mode);
public RNode toResponseObject() {
return new RNode(id, mode);
}
}

View File

@ -3,8 +3,11 @@ package ru.dragonestia.picker.model;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import ru.dragonestia.picker.model.type.SlotLimit;
import java.util.HashMap;
@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Room {
@ -44,9 +47,13 @@ public class Room {
return false;
}
public ru.dragonestia.picker.api.model.Room toResponseObject() {
var result = new ru.dragonestia.picker.api.model.Room(id, nodeId, slots.getSlots(), payload);
public RRoom toResponseObject() {
var result = new RRoom(id, nodeId, slots.getSlots(), payload);
result.setLocked(locked);
return result;
}
public RRoom.Short toShortResponseObject() {
return new RRoom.Short(id, slots.getSlots(), locked, new HashMap<>());
}
}

View File

@ -1,6 +1,7 @@
package ru.dragonestia.picker.model;
import lombok.NonNull;
import ru.dragonestia.picker.api.repository.response.type.RUser;
public record User(@NonNull String id) {
@ -19,7 +20,7 @@ public record User(@NonNull String id) {
return false;
}
public ru.dragonestia.picker.api.model.User toResponseObject() {
return new ru.dragonestia.picker.api.model.User(id);
public RUser toResponseObject() {
return new RUser(id);
}
}

View File

@ -2,7 +2,7 @@ package ru.dragonestia.picker.repository.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;
import ru.dragonestia.picker.repository.UserRepository;

View File

@ -1,6 +1,6 @@
package ru.dragonestia.picker.repository.impl.picker;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;
import ru.dragonestia.picker.repository.UserRepository;

View File

@ -1,6 +1,6 @@
package ru.dragonestia.picker.repository.impl.picker;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;

View File

@ -1,6 +1,6 @@
package ru.dragonestia.picker.repository.impl.picker;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;
import ru.dragonestia.picker.repository.UserRepository;

View File

@ -1,6 +1,6 @@
package ru.dragonestia.picker.repository.impl.picker;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;
import ru.dragonestia.picker.repository.UserRepository;

View File

@ -2,10 +2,13 @@ package ru.dragonestia.picker.service;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.api.repository.details.NodeDetails;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.model.Node;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface NodeService {
@ -15,5 +18,7 @@ public interface NodeService {
List<Node> all();
List<RNode> getAllNodesWithDetailsResponse(Set<NodeDetails> details);
Optional<Node> find(String nodeId);
}

View File

@ -2,12 +2,15 @@ package ru.dragonestia.picker.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.response.type.RRoom;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.Node;
import ru.dragonestia.picker.model.User;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface RoomService {
@ -19,6 +22,8 @@ public interface RoomService {
List<Room> all(Node node);
List<RRoom.Short> getAllRoomsWithDetailsResponse(Node node, Set<RoomDetails> details);
default int countAvailable(Node node) {
return countAvailable(node, 1);
}

View File

@ -1,11 +1,14 @@
package ru.dragonestia.picker.service;
import ru.dragonestia.picker.api.exception.RoomAreFullException;
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 java.util.Collection;
import java.util.List;
import java.util.Set;
public interface UserService {
@ -16,4 +19,6 @@ public interface UserService {
void unlinkUsersFromRoom(Room room, Collection<User> users);
List<User> getRoomUsers(Room room);
List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details);
}

View File

@ -4,13 +4,17 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.api.repository.details.NodeDetails;
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.NamingValidator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Service
@RequiredArgsConstructor
@ -35,6 +39,21 @@ public class NodeServiceImpl implements NodeService {
return nodeRepository.all();
}
@Override
public List<RNode> getAllNodesWithDetailsResponse(Set<NodeDetails> details) {
var response = new LinkedList<RNode>();
for (var node: all()) {
var responseNode = node.toResponseObject();
for (var detail: details) {
// TODO...
}
response.add(responseNode);
}
return response;
}
@Override
public Optional<Node> find(String nodeId) {
return nodeRepository.find(nodeId);

View File

@ -1,24 +1,33 @@
package ru.dragonestia.picker.service.impl;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
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.NamingValidator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Log4j2
@Service
@RequiredArgsConstructor
public class RoomServiceImpl implements RoomService {
private final RoomRepository roomRepository;
private final UserRepository userRepository;
private final NamingValidator namingValidator;
@Override
@ -42,6 +51,24 @@ public class RoomServiceImpl implements RoomService {
return roomRepository.all(node);
}
@Override
public List<RRoom.Short> getAllRoomsWithDetailsResponse(Node node, Set<RoomDetails> details) {
var response = new LinkedList<RRoom.Short>();
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);
}
return response;
}
@Override
public int countAvailable(Node node, int requiredSlots) {
throw new RuntimeException("Not implemented");

View File

@ -2,19 +2,22 @@ package ru.dragonestia.picker.service.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
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 java.util.Collection;
import java.util.List;
import java.util.*;
import java.util.function.Function;
@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final Map<UserDetails, Function<User, String>> detailsMap = new HashMap<>();
@Override
public List<Room> getUserRooms(User user) {
@ -36,4 +39,21 @@ public class UserServiceImpl implements UserService {
public List<User> getRoomUsers(Room room) {
return userRepository.usersOf(room);
}
@Override
public List<RUser> getRoomUsersWithDetailsResponse(Room room, Set<UserDetails> details) {
var users = new LinkedList<RUser>();
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);
}
return users;
}
}

View File

@ -3,7 +3,7 @@ package ru.dragonestia.picker.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import ru.dragonestia.picker.model.Node;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;

View File

@ -12,8 +12,8 @@ import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import lombok.Getter;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.model.User;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import ru.dragonestia.picker.api.repository.response.type.RUser;
import java.util.Collection;
import java.util.List;
@ -21,12 +21,12 @@ import java.util.function.BiConsumer;
public class AddUsers extends Details {
private final Room room;
private final BiConsumer<Collection<User>, Boolean> onCommit;
private final RRoom room;
private final BiConsumer<Collection<RUser>, Boolean> onCommit;
private final Checkbox ignoreSlots;
private final VerticalLayout usersLayout;
public AddUsers(Room room, BiConsumer<Collection<User>, Boolean> onCommit) {
public AddUsers(RRoom room, BiConsumer<Collection<RUser>, Boolean> onCommit) {
super(new H2("Add users"));
this.room = room;
@ -46,14 +46,14 @@ public class AddUsers extends Details {
usersLayout.add(new UserEntry(false));
}
public List<User> readAllUsers() {
public List<RUser> readAllUsers() {
return usersLayout.getChildren()
.filter(component -> component instanceof UserEntry)
.map(component -> (UserEntry) component)
.map(user -> user.getUserIdentifierField().getValue())
.map(String::trim)
.filter(user -> !user.isEmpty())
.map(User::new)
.map(RUser::new)
.toList();
}

View File

@ -6,7 +6,6 @@ import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
@ -14,19 +13,19 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.value.ValueChangeMode;
import lombok.Setter;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import java.util.List;
import java.util.function.Consumer;
public class NodeList extends VerticalLayout {
private final Grid<Node> nodesGrid;
private final Grid<RNode> nodesGrid;
private final TextField searchField;
private List<Node> cachedNodes;
private List<RNode> cachedNodes;
@Setter private Consumer<String> removeMethod;
public NodeList(List<Node> nodes) {
public NodeList(List<RNode> nodes) {
super();
cachedNodes = nodes;
@ -56,15 +55,15 @@ public class NodeList extends VerticalLayout {
.toList());
}
private Grid<Node> createGrid() {
var grid = new Grid<>(Node.class, false);
grid.addColumn(Node::getId).setHeader("Identifier");
private Grid<RNode> createGrid() {
var grid = new Grid<>(RNode.class, false);
grid.addColumn(RNode::getId).setHeader("Identifier");
grid.addColumn(node -> node.getMode().getName()).setHeader("Mode");
grid.addComponentColumn(this::createManageButtons).setHeader("Manage");
return grid;
}
private HorizontalLayout createManageButtons(Node node) {
private HorizontalLayout createManageButtons(RNode node) {
var layout = new HorizontalLayout();
{
@ -84,11 +83,11 @@ public class NodeList extends VerticalLayout {
return layout;
}
private void clickDetailsButton(Node node) {
private void clickDetailsButton(RNode node) {
getUI().ifPresent(ui -> ui.navigate("/nodes/" + node.getId()));
}
private void clickRemoveButton(Node node) {
private void clickRemoveButton(RNode node) {
var dialog = new Dialog("Confirm node deletion");
dialog.add(new Html("<p>Confirm that you want to delete node. Enter <b><u>" + node.getId() + "</u></b> to field below and confirm.</p>"));
@ -122,12 +121,12 @@ public class NodeList extends VerticalLayout {
dialog.open();
}
public void update(List<Node> nodes) {
public void update(List<RNode> nodes) {
cachedNodes = nodes;
applySearch(searchField.getValue());
}
private void removeNode(Node node) {
private void removeNode(RNode node) {
if (removeMethod != null) {
removeMethod.accept(node.getId());
}

View File

@ -14,18 +14,18 @@ import com.vaadin.flow.component.textfield.Autocomplete;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import org.springframework.lang.Nullable;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.model.type.PickingMode;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
import java.util.function.Function;
public class RegisterNode extends Details {
private final Function<Node, Response> onSubmit;
private final Function<RNode, Response> onSubmit;
private final TextField identifierField;
private final RadioButtonGroup<PickingMode> modeRadio;
public RegisterNode(Function<Node, Response> onSubmit) {
public RegisterNode(Function<RNode, Response> onSubmit) {
super(new H2("Register node"));
this.onSubmit = onSubmit;
@ -93,7 +93,7 @@ public class RegisterNode extends Details {
return;
}
var node = new Node(nodeIdentifier, modeRadio.getValue());
var node = new RNode(nodeIdentifier, modeRadio.getValue());
var response = onSubmit.apply(node);
clear();
if (response.error()) {

View File

@ -11,20 +11,20 @@ import com.vaadin.flow.component.textfield.Autocomplete;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.textfield.TextField;
import org.springframework.lang.Nullable;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import java.util.function.Function;
public class RegisterRoom extends Details {
private final Node node;
private final Function<Room, Response> onSubmit;
private final RNode node;
private final Function<RRoom, Response> onSubmit;
private final TextField identifierField;
private final TextArea payloadField;
private final Checkbox lockedField;
public RegisterRoom(Node node, Function<Room, Response> onSubmit) {
public RegisterRoom(RNode node, Function<RRoom, Response> onSubmit) {
super(new H2("Register room"));
this.node = node;
this.onSubmit = onSubmit;
@ -107,7 +107,7 @@ public class RegisterRoom extends Details {
return;
}
var room = new Room(nodeIdentifier, node, Room.INFINITE_SLOTS, payloadField.getValue());
var room = new RRoom(nodeIdentifier, node, RRoom.INFINITE_SLOTS, payloadField.getValue());
room.setLocked(lockedField.getValue());
var response = onSubmit.apply(room);
clear();

View File

@ -7,7 +7,6 @@ import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.grid.ColumnTextAlign;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
@ -16,20 +15,24 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.value.ValueChangeMode;
import lombok.Setter;
import ru.dragonestia.picker.api.model.Room;
import lombok.extern.log4j.Log4j2;
import ru.dragonestia.picker.api.repository.details.RoomDetails;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import java.util.List;
import java.util.function.Consumer;
@Log4j2
public class RoomList extends VerticalLayout {
private final String nodeIdentifier;
private final Grid<Room.Short> roomsGrid;
private final Grid<RRoom.Short> roomsGrid;
private final TextField searchField;
private List<Room.Short> cachedRooms;
@Setter private Consumer<Room.Short> removeMethod;
private List<RRoom.Short> cachedRooms;
private final Span totalUsers = new Span();
@Setter private Consumer<RRoom.Short> removeMethod;
public RoomList(String nodeIdentifier, List<Room.Short> buckets) {
public RoomList(String nodeIdentifier, List<RRoom.Short> buckets) {
this.nodeIdentifier = nodeIdentifier;
cachedRooms = buckets;
@ -58,9 +61,10 @@ public class RoomList extends VerticalLayout {
.toList());
}
private Grid<Room.Short> createGrid() {
var grid = new Grid<>(Room.Short.class, false);
grid.addColumn(Room.Short::id).setHeader("Identifier");
private Grid<RRoom.Short> createGrid() {
var grid = new Grid<>(RRoom.Short.class, false);
grid.addColumn(RRoom.Short::id).setHeader("Identifier");
grid.addComponentColumn(room -> {
var result = new Span();
if (room.slots() == -1) {
@ -71,6 +75,12 @@ public class RoomList extends VerticalLayout {
}
return result;
}).setHeader("Slots").setTextAlign(ColumnTextAlign.CENTER);
grid.addColumn(this::getUsers).setHeader("Users").setTextAlign(ColumnTextAlign.CENTER).setFooter(totalUsers);
grid.addColumn(room -> UserList.getUsingPercentage(room.slots(), getUsers(room)))
.setHeader("Occupancy").setTextAlign(ColumnTextAlign.CENTER);
grid.addComponentColumn(room -> {
var result = new Span();
if (room.locked()) {
@ -81,11 +91,12 @@ public class RoomList extends VerticalLayout {
}
return result;
}).setHeader("Locked").setTextAlign(ColumnTextAlign.CENTER);
grid.addComponentColumn(this::createManageButtons).setHeader("Manage");
return grid;
}
private HorizontalLayout createManageButtons(Room.Short room) {
private HorizontalLayout createManageButtons(RRoom.Short room) {
var layout = new HorizontalLayout();
{
@ -105,14 +116,14 @@ public class RoomList extends VerticalLayout {
return layout;
}
private void clickDetailsButton(Room.Short bucket) {
private void clickDetailsButton(RRoom.Short bucket) {
getUI().ifPresent(ui -> {
ui.navigate("/nodes/" + nodeIdentifier +
"/rooms/" + bucket.id());
});
}
private void clickRemoveButton(Room.Short bucket) {
private void clickRemoveButton(RRoom.Short bucket) {
var dialog = new Dialog("Confirm bucket deletion");
dialog.add(new Html("<p>Confirm that you want to delete bucket. Enter <b><u>" + bucket.id() + "</u></b> to field below and confirm.</p>"));
@ -146,14 +157,28 @@ public class RoomList extends VerticalLayout {
dialog.open();
}
public void update(List<Room.Short> buckets) {
public void update(List<RRoom.Short> buckets) {
cachedRooms = buckets;
applySearch(searchField.getValue());
int users = 0;
for (var room: cachedRooms) {
users += getUsers(room);
}
totalUsers.setText("Total users: " + users);
}
private void removeBucket(Room.Short bucket) {
private void removeBucket(RRoom.Short bucket) {
if (removeMethod != null) {
removeMethod.accept(bucket);
}
}
private int getUsers(RRoom.Short room) {
try {
return Integer.parseInt(room.details().getOrDefault(RoomDetails.COUNT_USERS, "0"));
} catch (NumberFormatException ex) {
return 0;
}
}
}

View File

@ -4,21 +4,22 @@ 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.orderedlayout.VerticalLayout;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.model.User;
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.ArrayList;
import java.util.List;
public class UserList extends VerticalLayout {
private final Room room;
private final Grid<User> usersGrid;
private final RRoom room;
private final Grid<RUser> usersGrid;
private final Span totalUsers = new Span();
private final Span occupancy = new Span();
private List<User> cachedUsers = new ArrayList<>();
private List<RUser> cachedUsers = new ArrayList<>();
public UserList(Room room, List<User> users) {
public UserList(RRoom room, List<RUser> users) {
this.room = room;
add(usersGrid = createUsersGrid());
@ -26,25 +27,25 @@ public class UserList extends VerticalLayout {
update(users);
}
private Grid<User> createUsersGrid() {
var grid = new Grid<User>();
grid.addColumn(User::getId).setHeader("User Identifier").setFooter(totalUsers);
grid.addColumn(user -> 0).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms") // TODO
private Grid<RUser> createUsersGrid() {
var grid = new Grid<RUser>();
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
return grid;
}
public void update(List<User> users) {
public void update(List<RUser> users) {
cachedUsers = users;
usersGrid.setItems(users);
totalUsers.setText("Total users: " + users.size());
occupancy.setText("Occupancy: %s".formatted(getUsingPercentage(room, users.size())));
occupancy.setText("Occupancy: %s".formatted(getUsingPercentage(room.getSlots(), users.size())));
}
private String getUsingPercentage(Room room, int usedSlots) {
if (room.isUnlimited()) return "0%";
double percent = usedSlots / (double) room.getSlots() * 100;
public static String getUsingPercentage(int slots, int usedSlots) {
if (slots == RRoom.INFINITE_SLOTS) return "N/A";
double percent = usedSlots / (double) slots * 100;
return ((int) percent) + "%";
}
}

View File

@ -3,7 +3,6 @@ package ru.dragonestia.picker.cp.page;
import com.vaadin.flow.component.Html;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Hr;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
@ -11,18 +10,18 @@ import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.repository.details.RoomDetails;
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.cp.component.Notifications;
import ru.dragonestia.picker.cp.component.RoomList;
import ru.dragonestia.picker.cp.component.NavPath;
import ru.dragonestia.picker.cp.component.RegisterRoom;
import ru.dragonestia.picker.cp.util.RouteParamsExtractor;
import java.util.List;
import java.util.Set;
@Getter
@RequiredArgsConstructor
@ -34,7 +33,7 @@ public class NodeDetailsPage extends VerticalLayout implements BeforeEnterObserv
private final RoomRepository roomRepository;
private final RouteParamsExtractor paramsExtractor;
private Node node;
private RNode node;
private RegisterRoom registerRoom;
private RoomList roomList;
@ -42,10 +41,10 @@ public class NodeDetailsPage extends VerticalLayout implements BeforeEnterObserv
public void beforeEnter(BeforeEnterEvent event) {
node = paramsExtractor.extractNodeId(event);
initComponents(node, roomRepository.all(node));
initComponents(node, roomRepository.all(node, RoomRepository.ALL_DETAILS));
}
private void initComponents(Node node, List<Room.Short> rooms) {
private void initComponents(RNode node, List<RRoom.Short> rooms) {
add(NavPath.toNode(node.getId()));
printNodeDetails(node);
add(new Hr());
@ -56,18 +55,18 @@ public class NodeDetailsPage extends VerticalLayout implements BeforeEnterObserv
} catch (Error error) {
return new RegisterRoom.Response(true, error.getMessage());
} finally {
roomList.update(roomRepository.all(node));
roomList.update(roomRepository.all(node, RoomRepository.ALL_DETAILS));
}
}));
add(new Hr());
add(roomList = new RoomList(node.getId(), rooms));
roomList.setRemoveMethod(room -> {
roomRepository.remove(node, room);
roomList.update(roomRepository.all(node));
roomList.update(roomRepository.all(node, RoomRepository.ALL_DETAILS));
});
}
private void printNodeDetails(Node node) {
private void printNodeDetails(RNode node) {
add(new H2("Node details"));
var layout = new VerticalLayout();

View File

@ -33,7 +33,7 @@ public class NodesPage extends VerticalLayout {
add(nodeList = createNodeListElement());
nodeList.setRemoveMethod(nodeIdentifier -> {
nodeRepository.remove(nodeIdentifier);
nodeList.update(nodeRepository.all());
nodeList.update(nodeRepository.all(NodeRepository.ALL_DETAILS));
});
}
@ -45,12 +45,12 @@ public class NodesPage extends VerticalLayout {
} catch (ApiException ex) {
return new RegisterNode.Response(true, ex.getMessage());
} finally {
nodeList.update(nodeRepository.all());
nodeList.update(nodeRepository.all(NodeRepository.ALL_DETAILS));
}
});
}
protected NodeList createNodeListElement() {
return new NodeList(nodeRepository.all());
return new NodeList(nodeRepository.all(NodeRepository.ALL_DETAILS));
}
}

View File

@ -5,7 +5,6 @@ import com.vaadin.flow.component.Unit;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Hr;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
@ -15,13 +14,13 @@ import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.model.User;
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.api.repository.NodeRepository;
import ru.dragonestia.picker.api.repository.RoomRepository;
import ru.dragonestia.picker.api.repository.UserRepository;
import ru.dragonestia.picker.api.repository.details.UserDetails;
import ru.dragonestia.picker.cp.component.AddUsers;
import ru.dragonestia.picker.cp.component.NavPath;
import ru.dragonestia.picker.cp.component.Notifications;
@ -29,6 +28,7 @@ import ru.dragonestia.picker.cp.component.UserList;
import ru.dragonestia.picker.cp.util.RouteParamsExtractor;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@RequiredArgsConstructor
@ -41,8 +41,8 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
private final UserRepository userRepository;
private final RouteParamsExtractor paramsExtractor;
private Node node;
private Room room;
private RNode node;
private RRoom room;
private AddUsers addUsers;
private UserList userList;
private Button lockRoomButton;
@ -64,7 +64,7 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
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)));
add(userList = new UserList(room, userRepository.all(room, UserRepository.ALL_DETAILS)));
}
private void updateRoomInfo() {
@ -111,7 +111,7 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
Notifications.success("Success");
}
private void appendUsers(Room room, Collection<User> users, boolean ignoreLimitation) {
private void appendUsers(RRoom room, Collection<RUser> users, boolean ignoreLimitation) {
AtomicBoolean validationFail = new AtomicBoolean(false);
var newUsers = users.stream()
@ -125,7 +125,7 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
}).toList();
userRepository.linkWithRoom(room, newUsers, ignoreLimitation);
userList.update(userRepository.all(room));
userList.update(userRepository.all(room, UserRepository.ALL_DETAILS));
if (validationFail.get()) {
if (newUsers.isEmpty()) {

View File

@ -7,13 +7,15 @@ import org.springframework.http.HttpMethod;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
import ru.dragonestia.picker.api.repository.details.NodeDetails;
import ru.dragonestia.picker.api.repository.response.NodeDetailsResponse;
import ru.dragonestia.picker.api.repository.response.NodeListResponse;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.api.repository.NodeRepository;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Log4j2
@RequiredArgsConstructor
@ -23,7 +25,7 @@ public class NodeRepositoryImpl implements NodeRepository {
private final RestUtil rest;
@Override
public void register(Node node) throws InvalidNodeIdentifierException, NodeAlreadyExistException {
public void register(RNode node) throws InvalidNodeIdentifierException, NodeAlreadyExistException {
rest.query("nodes", HttpMethod.POST, params -> {
params.put("nodeId", node.getId());
params.put("method", node.getMode().name());
@ -31,12 +33,14 @@ public class NodeRepositoryImpl implements NodeRepository {
}
@Override
public List<Node> all() {
return rest.query("nodes", HttpMethod.GET, NodeListResponse.class, params -> {}).nodes();
public List<RNode> all(Set<NodeDetails> details) {
return rest.query("nodes", HttpMethod.GET, NodeListResponse.class, params -> {
params.put("requiredDetails", String.join(",", details.stream().map(Enum::toString).toList()));
}).nodes();
}
@Override
public Optional<Node> find(String nodeId) {
public Optional<RNode> find(String nodeId) {
try {
var response = rest.query("nodes/" + nodeId, HttpMethod.GET, NodeDetailsResponse.class, params -> {});
return Optional.of(response.node());

View File

@ -8,14 +8,16 @@ import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException;
import ru.dragonestia.picker.api.exception.NodeNotFoundException;
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
import ru.dragonestia.picker.api.exception.RoomNotFoundException;
import ru.dragonestia.picker.api.model.Node;
import ru.dragonestia.picker.api.model.Room;
import ru.dragonestia.picker.api.repository.details.RoomDetails;
import ru.dragonestia.picker.api.repository.response.type.RNode;
import ru.dragonestia.picker.api.repository.response.type.RRoom;
import ru.dragonestia.picker.api.repository.RoomRepository;
import ru.dragonestia.picker.api.repository.response.RoomInfoResponse;
import ru.dragonestia.picker.api.repository.response.RoomListResponse;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Log4j2
@RequiredArgsConstructor
@ -25,7 +27,7 @@ public class RoomRepositoryImpl implements RoomRepository {
private final RestUtil rest;
@Override
public void register(Room room) throws NodeNotFoundException, InvalidRoomIdentifierException, RoomAlreadyExistException {
public void register(RRoom room) throws NodeNotFoundException, InvalidRoomIdentifierException, RoomAlreadyExistException {
rest.query("/nodes/" + room.getNodeId() + "/rooms", HttpMethod.POST, params -> {
params.put("roomId", room.getId());
params.put("slots", Integer.toString(room.getSlots()));
@ -35,22 +37,24 @@ public class RoomRepositoryImpl implements RoomRepository {
}
@Override
public void remove(Room room) throws NodeNotFoundException {
public void remove(RRoom room) throws NodeNotFoundException {
rest.query("/nodes/" + room.getNodeId() + "/rooms/" + room.getId(), HttpMethod.DELETE, params -> {});
}
@Override
public void remove(Node node, Room.Short room) throws NodeNotFoundException {
public void remove(RNode node, RRoom.Short room) throws NodeNotFoundException {
rest.query("/nodes/" + node.getId() + "/rooms/" + room.id(), HttpMethod.DELETE, params -> {});
}
@Override
public List<Room.Short> all(Node node) throws NodeNotFoundException {
return rest.query("/nodes/" + node.getId() + "/rooms", HttpMethod.GET, RoomListResponse.class, params -> {}).rooms();
public List<RRoom.Short> all(RNode node, Set<RoomDetails> details) throws NodeNotFoundException {
return rest.query("/nodes/" + node.getId() + "/rooms", HttpMethod.GET, RoomListResponse.class, params -> {
params.put("requiredDetails", String.join(",", details.stream().map(Enum::toString).toList()));
}).rooms();
}
@Override
public Optional<Room> find(Node node, String roomId) throws NodeNotFoundException {
public Optional<RRoom> find(RNode node, String roomId) throws NodeNotFoundException {
try {
var response = rest.query("/nodes/" + node.getId() + "/rooms/" + roomId, HttpMethod.GET, RoomInfoResponse.class, map -> {});
return Optional.of(response.room());
@ -60,7 +64,7 @@ public class RoomRepositoryImpl implements RoomRepository {
}
@Override
public void lock(Room room, boolean value) throws NodeNotFoundException, RoomNotFoundException {
public void lock(RRoom room, boolean value) throws NodeNotFoundException, RoomNotFoundException {
rest.query("/nodes/%s/rooms/%s/lock".formatted(room.getNodeId(), room.getId()), HttpMethod.PUT, params -> {
params.put("newState", Boolean.toString(value));
});

View File

@ -7,13 +7,15 @@ 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.model.Room;
import ru.dragonestia.picker.api.model.User;
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;
@Log4j2
@RequiredArgsConstructor
@ -23,29 +25,33 @@ public class UserRepositoryImpl implements UserRepository {
private final RestUtil rest;
@Override
public void linkWithRoom(Room room, Collection<User> users, boolean force) throws NodeNotFoundException, RoomNotFoundException, RoomAreFullException {
public void linkWithRoom(RRoom room, Collection<RUser> users, boolean force) throws NodeNotFoundException, RoomNotFoundException, RoomAreFullException {
rest.query("/nodes/%s/rooms/%s/users".formatted(room.getNodeId(), room.getId()),
HttpMethod.POST,
params -> {
params.put("userIds", String.join(",", users.stream().map(User::getId).toList()));
params.put("userIds", String.join(",", users.stream().map(RUser::getId).toList()));
params.put("force", Boolean.toString(force));
});
}
@Override
public void unlinkFromRoom(Room room, Collection<User> users) throws NodeNotFoundException, RoomNotFoundException {
public void unlinkFromRoom(RRoom room, Collection<RUser> users) throws NodeNotFoundException, RoomNotFoundException {
rest.query("/nodes/%s/rooms/%s/users".formatted(room.getNodeId(), room.getId()),
HttpMethod.DELETE,
params -> {
params.put("userIds", String.join(",", users.stream().map(User::getId).toList()));
params.put("userIds", String.join(",", users.stream().map(RUser::getId).toList()));
});
}
@Override
public List<User> all(Room room) throws NodeNotFoundException, RoomNotFoundException {
public List<RUser> all(RRoom room, Set<UserDetails> details) throws NodeNotFoundException, RoomNotFoundException {
return rest.query("/nodes/%s/rooms/%s/users".formatted(room.getNodeId(), room.getId()),
HttpMethod.GET,
RoomUserListResponse.class,
params -> {}).users();
params -> {
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
params.put("requiredDetails", detailsStr);
}).users();
}
}

View File

@ -5,8 +5,8 @@ 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.model.Node;
import ru.dragonestia.picker.api.model.Room;
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;
@ -17,12 +17,12 @@ public class RouteParamsExtractor {
private final NodeRepository nodeRepository;
private final RoomRepository roomRepository;
public Node extractNodeId(BeforeEnterEvent e) throws NodeNotFoundException {
public RNode extractNodeId(BeforeEnterEvent e) throws NodeNotFoundException {
var nodeId = e.getRouteParameters().get("nodeId").orElseThrow(() -> new NodeNotFoundException("null"));
return nodeRepository.find(nodeId).orElseThrow(() -> new NodeNotFoundException(nodeId));
}
public Room extractRoomId(BeforeEnterEvent e, Node node) throws RoomNotFoundException {
public RRoom extractRoomId(BeforeEnterEvent e, RNode node) throws RoomNotFoundException {
var roomId = e.getRouteParameters().get("roomId").orElseThrow(() -> new NodeNotFoundException("null"));
return roomRepository.find(node, roomId).orElseThrow(() -> new NodeNotFoundException(roomId));
}