Refactored control panel
This commit is contained in:
parent
a29471f2c5
commit
0ba5ff8045
@ -2,6 +2,7 @@ package ru.dragonestia.picker.api.model.room;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.dragonestia.picker.api.repository.type.RoomPath;
|
||||
@ -64,11 +65,23 @@ public class ResponseRoom implements IRoom {
|
||||
return slots;
|
||||
}
|
||||
|
||||
@Contract("_ -> this")
|
||||
public @NotNull ResponseRoom setSlots(int slots) {
|
||||
this.slots = slots;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
@Contract("_ -> this")
|
||||
public @NotNull ResponseRoom setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Boolean isPersist() {
|
||||
var val = getDetail(RoomDetails.PERSIST);
|
||||
@ -80,6 +93,12 @@ public class ResponseRoom implements IRoom {
|
||||
return payload;
|
||||
}
|
||||
|
||||
@Contract("_ -> this")
|
||||
public @NotNull ResponseRoom setPayload(@NotNull String payload) {
|
||||
this.payload = payload;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Transient
|
||||
@Override
|
||||
public boolean hasUnlimitedSlots() {
|
||||
|
||||
@ -5,8 +5,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.picker.api.model.room.RoomDetails;
|
||||
import ru.dragonestia.picker.api.repository.type.UserIdentifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FindRoomsLinkedWithUser {
|
||||
|
||||
@ -26,6 +28,21 @@ public class FindRoomsLinkedWithUser {
|
||||
return details;
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static @NotNull FindRoomsLinkedWithUser just(@NotNull UserIdentifier identifier) {
|
||||
return FindRoomsLinkedWithUser.builder()
|
||||
.setUserId(identifier)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static @NotNull FindRoomsLinkedWithUser withAllDetails(@NotNull UserIdentifier identifier) {
|
||||
return FindRoomsLinkedWithUser.builder()
|
||||
.setUserId(identifier)
|
||||
.setDetails(Arrays.stream(RoomDetails.values()).collect(Collectors.toSet()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static @NotNull Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@ -6,9 +6,11 @@ import ru.dragonestia.picker.api.model.user.UserDetails;
|
||||
import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
|
||||
import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GetAllUsersFromRoom {
|
||||
|
||||
@ -34,6 +36,21 @@ public class GetAllUsersFromRoom {
|
||||
return details;
|
||||
}
|
||||
|
||||
public static @NotNull GetAllUsersFromRoom just(@NotNull NodeIdentifier nodeId, @NotNull RoomIdentifier roomId) {
|
||||
return GetAllUsersFromRoom.builder()
|
||||
.setNodeId(nodeId)
|
||||
.setRoomId(roomId)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static @NotNull GetAllUsersFromRoom withAllDetails(@NotNull NodeIdentifier nodeId, @NotNull RoomIdentifier roomId) {
|
||||
return GetAllUsersFromRoom.builder()
|
||||
.setNodeId(nodeId)
|
||||
.setRoomId(roomId)
|
||||
.setDetails(Arrays.stream(UserDetails.values()).collect(Collectors.toSet()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static @NotNull Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ vaadin {
|
||||
|
||||
dependencies {
|
||||
implementation project(":client-api")
|
||||
implementation project(":client-impl")
|
||||
|
||||
implementation 'com.vaadin:vaadin-spring-boot-starter'
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package ru.dragonestia.picker.cp.annotation;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Qualifier
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
||||
public @interface ServerURL {}
|
||||
@ -12,8 +12,10 @@ 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.repository.response.type.RRoom;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.api.model.room.IRoom;
|
||||
import ru.dragonestia.picker.api.model.user.IUser;
|
||||
import ru.dragonestia.picker.api.model.user.UserDefinition;
|
||||
import ru.dragonestia.picker.api.repository.type.UserIdentifier;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -22,16 +24,14 @@ import java.util.function.BiConsumer;
|
||||
|
||||
public class AddUsers extends Details {
|
||||
|
||||
private final RRoom room;
|
||||
private final BiConsumer<Collection<RUser>, Boolean> onCommit;
|
||||
private final BiConsumer<Collection<IUser>, Boolean> onCommit;
|
||||
private final Checkbox ignoreSlots;
|
||||
private final VerticalLayout usersLayout;
|
||||
private final AtomicInteger freeUserIdNumber = new AtomicInteger(1);
|
||||
|
||||
public AddUsers(RRoom room, BiConsumer<Collection<RUser>, Boolean> onCommit) {
|
||||
public AddUsers(IRoom room, BiConsumer<Collection<IUser>, Boolean> onCommit) {
|
||||
super(new H2("Add users"));
|
||||
|
||||
this.room = room;
|
||||
this.onCommit = onCommit;
|
||||
usersLayout = new VerticalLayout();
|
||||
|
||||
@ -49,14 +49,14 @@ public class AddUsers extends Details {
|
||||
usersLayout.add(new UserEntry(false, freeUserIdNumber.getAndIncrement()));
|
||||
}
|
||||
|
||||
public List<RUser> readAllUsers() {
|
||||
public List<IUser> 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(RUser::new)
|
||||
.map(id -> (IUser) new UserDefinition(UserIdentifier.of(id)))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
@ -14,22 +14,20 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
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.INode;
|
||||
import ru.dragonestia.picker.api.model.node.NodeDetails;
|
||||
import ru.dragonestia.picker.api.repository.NodeRepository;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RNode;
|
||||
import ru.dragonestia.picker.api.repository.request.node.GetAllNodes;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class NodeList extends VerticalLayout implements RefreshableTable {
|
||||
|
||||
private final NodeRepository nodeRepository;
|
||||
private final Grid<RNode> nodesGrid;
|
||||
private final Grid<INode> nodesGrid;
|
||||
private final TextField searchField;
|
||||
private List<RNode> cachedNodes;
|
||||
@Setter private Consumer<String> removeMethod;
|
||||
private List<INode> cachedNodes;
|
||||
|
||||
public NodeList(NodeRepository nodeRepository) {
|
||||
super();
|
||||
@ -56,24 +54,24 @@ public class NodeList extends VerticalLayout implements RefreshableTable {
|
||||
var temp = input.trim();
|
||||
|
||||
nodesGrid.setItems(cachedNodes.stream()
|
||||
.filter(node -> node.getId().startsWith(temp))
|
||||
.filter(node -> node.getIdentifier().startsWith(temp))
|
||||
.toList());
|
||||
}
|
||||
|
||||
private Grid<RNode> createGrid() {
|
||||
var grid = new Grid<>(RNode.class, false);
|
||||
private Grid<INode> createGrid() {
|
||||
var grid = new Grid<>(INode.class, false);
|
||||
|
||||
grid.addComponentColumn(node -> {
|
||||
if (Boolean.parseBoolean(node.getDetails(NodeDetails.PERSIST))) {
|
||||
return new Span(node.getId());
|
||||
if (Boolean.parseBoolean(node.getDetail(NodeDetails.PERSIST))) {
|
||||
return new Span(node.getIdentifier());
|
||||
}
|
||||
|
||||
var result = new Span(node.getId());
|
||||
var result = new Span(node.getIdentifier());
|
||||
result.add(grayBadge("(temp)"));
|
||||
return result;
|
||||
}).setHeader("Identifier").setComparator(Comparator.comparing(RNode::getId)).setSortable(true);
|
||||
}).setHeader("Identifier").setComparator(Comparator.comparing(INode::getIdentifier)).setSortable(true);
|
||||
|
||||
grid.addColumn(node -> node.getMode().getName()).setHeader("Mode").setSortable(true);
|
||||
grid.addColumn(node -> node.getPickingMethod().name()).setHeader("Mode").setSortable(true);
|
||||
|
||||
grid.addComponentColumn(this::createManageButtons).setFrozenToEnd(true)
|
||||
.setTextAlign(ColumnTextAlign.END).setHeader(createRefreshButton());
|
||||
@ -82,7 +80,7 @@ public class NodeList extends VerticalLayout implements RefreshableTable {
|
||||
return grid;
|
||||
}
|
||||
|
||||
private HorizontalLayout createManageButtons(RNode node) {
|
||||
private HorizontalLayout createManageButtons(INode node) {
|
||||
var layout = new HorizontalLayout(JustifyContentMode.END);
|
||||
|
||||
{
|
||||
@ -102,13 +100,13 @@ public class NodeList extends VerticalLayout implements RefreshableTable {
|
||||
return layout;
|
||||
}
|
||||
|
||||
private void clickDetailsButton(RNode node) {
|
||||
getUI().ifPresent(ui -> ui.navigate("/nodes/" + node.getId()));
|
||||
private void clickDetailsButton(INode node) {
|
||||
getUI().ifPresent(ui -> ui.navigate("/nodes/" + node.getIdentifier()));
|
||||
}
|
||||
|
||||
private void clickRemoveButton(RNode node) {
|
||||
private void clickRemoveButton(INode 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>"));
|
||||
dialog.add(new Html("<p>Confirm that you want to delete node. Enter <b><u>" + node.getIdentifier() + "</u></b> to field below and confirm.</p>"));
|
||||
|
||||
var inputField = new TextField();
|
||||
inputField.setWidth("100%");
|
||||
@ -118,13 +116,13 @@ public class NodeList extends VerticalLayout implements RefreshableTable {
|
||||
var button = new Button("Confirm");
|
||||
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_ERROR);
|
||||
button.addClickListener(event -> {
|
||||
if (!node.getId().equals(inputField.getValue())) {
|
||||
if (!node.getIdentifier().equals(inputField.getValue())) {
|
||||
Notifications.error("Invalid input");
|
||||
return;
|
||||
}
|
||||
|
||||
removeNode(node);
|
||||
Notifications.success("Node <b>" + node.getId() + "</b> was successfully removed!");
|
||||
Notifications.success("Node <b>" + node.getIdentifier() + "</b> was successfully removed!");
|
||||
dialog.close();
|
||||
});
|
||||
|
||||
@ -140,15 +138,14 @@ public class NodeList extends VerticalLayout implements RefreshableTable {
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
private void removeNode(RNode node) {
|
||||
if (removeMethod != null) {
|
||||
removeMethod.accept(node.getId());
|
||||
}
|
||||
private void removeNode(INode node) {
|
||||
nodeRepository.removeNode(node);
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
cachedNodes = nodeRepository.all(NodeRepository.ALL_DETAILS);
|
||||
cachedNodes = nodeRepository.allNodes(GetAllNodes.WITH_ALL_DETAILS);
|
||||
applySearch(searchField.getValue());
|
||||
}
|
||||
|
||||
|
||||
@ -15,19 +15,20 @@ 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.repository.response.type.RNode;
|
||||
import ru.dragonestia.picker.api.repository.response.type.type.PickingMode;
|
||||
import ru.dragonestia.picker.api.model.node.NodeDefinition;
|
||||
import ru.dragonestia.picker.api.model.node.PickingMethod;
|
||||
import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class RegisterNode extends Details {
|
||||
|
||||
private final BiFunction<RNode, Boolean, Response> onSubmit;
|
||||
private final Function<NodeDefinition, Response> onSubmit;
|
||||
private final TextField identifierField;
|
||||
private final RadioButtonGroup<PickingMode> modeRadio;
|
||||
private final RadioButtonGroup<PickingMethod> modeRadio;
|
||||
private final Checkbox persistField;
|
||||
|
||||
public RegisterNode(BiFunction<RNode, Boolean, Response> onSubmit) {
|
||||
public RegisterNode(Function<NodeDefinition, Response> onSubmit) {
|
||||
super(new H2("Register node"));
|
||||
this.onSubmit = onSubmit;
|
||||
|
||||
@ -63,15 +64,15 @@ public class RegisterNode extends Details {
|
||||
return button;
|
||||
}
|
||||
|
||||
private RadioButtonGroup<PickingMode> createModeRadio() {
|
||||
var radio = new RadioButtonGroup<PickingMode>("Mode");
|
||||
private RadioButtonGroup<PickingMethod> createModeRadio() {
|
||||
var radio = new RadioButtonGroup<PickingMethod>("Mode");
|
||||
radio.addThemeVariants(RadioGroupVariant.LUMO_VERTICAL);
|
||||
radio.setRenderer(new ComponentRenderer<Component, PickingMode>(mode -> new Span(mode.getName())));
|
||||
radio.setItems(PickingMode.SEQUENTIAL_FILLING,
|
||||
PickingMode.ROUND_ROBIN,
|
||||
PickingMode.LEAST_PICKED);
|
||||
radio.setRenderer(new ComponentRenderer<Component, PickingMethod>(mode -> new Span(mode.name())));
|
||||
radio.setItems(PickingMethod.SEQUENTIAL_FILLING,
|
||||
PickingMethod.ROUND_ROBIN,
|
||||
PickingMethod.LEAST_PICKED);
|
||||
|
||||
radio.setValue(PickingMode.SEQUENTIAL_FILLING);
|
||||
radio.setValue(PickingMethod.SEQUENTIAL_FILLING);
|
||||
return radio;
|
||||
}
|
||||
|
||||
@ -101,8 +102,10 @@ public class RegisterNode extends Details {
|
||||
return;
|
||||
}
|
||||
|
||||
var node = new RNode(nodeIdentifier, modeRadio.getValue());
|
||||
var response = onSubmit.apply(node, persistField.getValue());
|
||||
var node = new NodeDefinition(NodeIdentifier.of(nodeIdentifier))
|
||||
.setPickingMethod(modeRadio.getValue())
|
||||
.setPersist(persistField.getValue());
|
||||
var response = onSubmit.apply(node);
|
||||
clear();
|
||||
if (response.error()) {
|
||||
Notifications.error(response.reason());
|
||||
|
||||
@ -11,22 +11,23 @@ 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.repository.response.type.RNode;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||
import ru.dragonestia.picker.api.model.node.INode;
|
||||
import ru.dragonestia.picker.api.model.room.IRoom;
|
||||
import ru.dragonestia.picker.api.model.room.RoomDefinition;
|
||||
import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class RegisterRoom extends Details {
|
||||
|
||||
private final RNode node;
|
||||
private final BiFunction<RRoom, Boolean, Response> onSubmit;
|
||||
private final INode node;
|
||||
private final Function<RoomDefinition, Response> onSubmit;
|
||||
private final TextField identifierField;
|
||||
private final TextArea payloadField;
|
||||
private final Checkbox lockedField;
|
||||
private final Checkbox persistField;
|
||||
|
||||
public RegisterRoom(RNode node, BiFunction<RRoom, Boolean, Response> onSubmit) {
|
||||
public RegisterRoom(INode node, Function<RoomDefinition, Response> onSubmit) {
|
||||
super(new H2("Register room"));
|
||||
this.node = node;
|
||||
this.onSubmit = onSubmit;
|
||||
@ -45,7 +46,7 @@ public class RegisterRoom extends Details {
|
||||
private TextField createNodeIdentifierField() {
|
||||
var field = new TextField("Node identifier");
|
||||
field.setMinWidth(20, Unit.REM);
|
||||
field.setValue(node.getId());
|
||||
field.setValue(node.getIdentifier());
|
||||
field.setReadOnly(true);
|
||||
return field;
|
||||
}
|
||||
@ -103,10 +104,10 @@ public class RegisterRoom extends Details {
|
||||
}
|
||||
|
||||
private void onClick() {
|
||||
var nodeIdentifier = identifierField.getValue();
|
||||
var roomId = identifierField.getValue();
|
||||
|
||||
String error = null;
|
||||
if (identifierField.isInvalid() || (error = validateForm(nodeIdentifier)) != null) {
|
||||
if (identifierField.isInvalid() || (error = validateForm(roomId)) != null) {
|
||||
if (identifierField.isInvalid()) {
|
||||
error = "Invalid room id format";
|
||||
}
|
||||
@ -115,9 +116,13 @@ public class RegisterRoom extends Details {
|
||||
return;
|
||||
}
|
||||
|
||||
var room = new RRoom(nodeIdentifier, node, RRoom.INFINITE_SLOTS, payloadField.getValue());
|
||||
var room = new RoomDefinition(node.getIdentifierObject(), RoomIdentifier.of(roomId))
|
||||
.setMaxSlots(IRoom.UNLIMITED_SLOTS)
|
||||
.setPayload(payloadField.getValue())
|
||||
.setPersist(persistField.getValue());
|
||||
|
||||
room.setLocked(lockedField.getValue());
|
||||
var response = onSubmit.apply(room, persistField.getValue());
|
||||
var response = onSubmit.apply(room);
|
||||
clear();
|
||||
if (response.error()) {
|
||||
Notifications.error(response.reason());
|
||||
|
||||
@ -14,28 +14,26 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
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 lombok.extern.log4j.Log4j2;
|
||||
import ru.dragonestia.picker.api.model.node.INode;
|
||||
import ru.dragonestia.picker.api.model.room.RoomDetails;
|
||||
import ru.dragonestia.picker.api.model.room.ShortResponseRoom;
|
||||
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RNode;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||
import ru.dragonestia.picker.api.repository.request.room.GetAllRooms;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Log4j2
|
||||
public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
|
||||
private final RNode node;
|
||||
private final INode node;
|
||||
private final RoomRepository roomRepository;
|
||||
private final Grid<RRoom.Short> roomsGrid;
|
||||
private final Grid<ShortResponseRoom> roomsGrid;
|
||||
private final TextField searchField;
|
||||
private List<RRoom.Short> cachedRooms;
|
||||
private List<ShortResponseRoom> cachedRooms;
|
||||
private final Span totalUsers = new Span();
|
||||
@Setter private Consumer<RRoom.Short> removeMethod;
|
||||
|
||||
public RoomList(RNode node, RoomRepository roomRepository) {
|
||||
public RoomList(INode node, RoomRepository roomRepository) {
|
||||
this.node = node;
|
||||
this.roomRepository = roomRepository;
|
||||
|
||||
@ -60,27 +58,27 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
var temp = input.trim();
|
||||
|
||||
roomsGrid.setItems(cachedRooms.stream()
|
||||
.filter(room -> room.id().startsWith(temp))
|
||||
.filter(room -> room.getIdentifier().startsWith(temp))
|
||||
.toList());
|
||||
}
|
||||
|
||||
private Grid<RRoom.Short> createGrid() {
|
||||
var grid = new Grid<>(RRoom.Short.class, false);
|
||||
private Grid<ShortResponseRoom> createGrid() {
|
||||
var grid = new Grid<>(ShortResponseRoom.class, false);
|
||||
|
||||
grid.addColumn(RRoom.Short::id).setHeader("Identifier").setSortable(true);
|
||||
grid.addColumn(ShortResponseRoom::getIdentifier).setHeader("Identifier").setSortable(true);
|
||||
|
||||
grid.addComponentColumn(room -> {
|
||||
var result = new Span();
|
||||
if (room.slots() == -1) {
|
||||
if (room.getMaxSlots() == -1) {
|
||||
result.setText("Unlimited");
|
||||
result.getElement().getThemeList().add("badge contrast");
|
||||
} else {
|
||||
result.setText(Integer.toString(room.slots()));
|
||||
result.setText(Integer.toString(room.getMaxSlots()));
|
||||
}
|
||||
return result;
|
||||
}).setHeader("Slots").setComparator((room1, room2) -> {
|
||||
var r1 = room1.slots() == -1? Integer.MAX_VALUE : room1.slots();
|
||||
var r2 = room2.slots() == -1? Integer.MAX_VALUE : room2.slots();
|
||||
var r1 = room1.hasUnlimitedSlots()? Integer.MAX_VALUE : room1.getMaxSlots();
|
||||
var r2 = room2.hasUnlimitedSlots()? Integer.MAX_VALUE : room2.getMaxSlots();
|
||||
|
||||
return Integer.compare(r1, r2);
|
||||
}).setSortable(true).setTextAlign(ColumnTextAlign.CENTER);
|
||||
@ -89,24 +87,24 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
.setComparator((room1, room2) -> Integer.compare(getUsers(room1), getUsers(room2))).setSortable(true)
|
||||
.setTextAlign(ColumnTextAlign.CENTER).setFooter(totalUsers);
|
||||
|
||||
grid.addColumn(room -> Math.max(UserList.getUsingPercentage(room.slots(), getUsers(room)), 0) + "%")
|
||||
grid.addColumn(room -> Math.max(UserList.getUsingPercentage(room.getMaxSlots(), getUsers(room)), 0) + "%")
|
||||
.setComparator((room1, room2) -> {
|
||||
var p1 = UserList.getUsingPercentage(room1.slots(), getUsers(room1));
|
||||
var p2 = UserList.getUsingPercentage(room2.slots(), getUsers(room2));
|
||||
var p1 = UserList.getUsingPercentage(room1.getMaxSlots(), getUsers(room1));
|
||||
var p2 = UserList.getUsingPercentage(room2.getMaxSlots(), getUsers(room2));
|
||||
|
||||
return Integer.compare(p1, p2);
|
||||
}).setHeader("Occupancy").setTextAlign(ColumnTextAlign.CENTER);
|
||||
|
||||
grid.addComponentColumn(room -> {
|
||||
var result = new Span();
|
||||
if (room.locked()) {
|
||||
if (room.isLocked()) {
|
||||
result.setText("Yes");
|
||||
result.getElement().getThemeList().add("badge error");
|
||||
} else {
|
||||
result.setText("No");
|
||||
}
|
||||
return result;
|
||||
}).setComparator((room1, room2) -> Boolean.compare(room1.locked(), room2.locked())).setSortable(true)
|
||||
}).setComparator((room1, room2) -> Boolean.compare(room1.isLocked(), room2.isLocked())).setSortable(true)
|
||||
.setHeader("Locked").setTextAlign(ColumnTextAlign.CENTER);
|
||||
|
||||
grid.addComponentColumn(this::createManageButtons).setFrozenToEnd(true)
|
||||
@ -116,7 +114,7 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
return grid;
|
||||
}
|
||||
|
||||
private HorizontalLayout createManageButtons(RRoom.Short room) {
|
||||
private HorizontalLayout createManageButtons(ShortResponseRoom room) {
|
||||
var layout = new HorizontalLayout(JustifyContentMode.END);
|
||||
|
||||
{
|
||||
@ -136,15 +134,15 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
return layout;
|
||||
}
|
||||
|
||||
private void clickDetailsButton(RRoom.Short room) {
|
||||
private void clickDetailsButton(ShortResponseRoom room) {
|
||||
getUI().ifPresent(ui -> {
|
||||
ui.navigate("/nodes/%s/rooms/%s".formatted(node.getId(), room.id()));
|
||||
ui.navigate("/nodes/%s/rooms/%s".formatted(node.getIdentifier(), room.getIdentifier()));
|
||||
});
|
||||
}
|
||||
|
||||
private void clickRemoveButton(RRoom.Short room) {
|
||||
private void clickRemoveButton(ShortResponseRoom room) {
|
||||
var dialog = new Dialog("Confirm room deletion");
|
||||
dialog.add(new Html("<p>Confirm that you want to delete room. Enter <b><u>" + room.id() + "</u></b> to field below and confirm.</p>"));
|
||||
dialog.add(new Html("<p>Confirm that you want to delete room. Enter <b><u>" + room.getIdentifier() + "</u></b> to field below and confirm.</p>"));
|
||||
|
||||
var inputField = new TextField();
|
||||
inputField.setWidth("100%");
|
||||
@ -154,13 +152,13 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
var button = new Button("Confirm");
|
||||
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_ERROR);
|
||||
button.addClickListener(event -> {
|
||||
if (!room.id().equals(inputField.getValue())) {
|
||||
if (!room.getIdentifier().equals(inputField.getValue())) {
|
||||
Notifications.error("Invalid input");
|
||||
return;
|
||||
}
|
||||
|
||||
removeRemove(room);
|
||||
Notifications.success("Room <b>" + room.id() + "</b> was successfully removed!");
|
||||
removeRoom(room);
|
||||
Notifications.success("Room <b>" + room.getIdentifier() + "</b> was successfully removed!");
|
||||
dialog.close();
|
||||
});
|
||||
|
||||
@ -176,15 +174,17 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
private void removeRemove(RRoom.Short room) {
|
||||
if (removeMethod != null) {
|
||||
removeMethod.accept(room);
|
||||
}
|
||||
public void removeRoom(ShortResponseRoom room) {
|
||||
roomRepository.removeRoom(room);
|
||||
refresh();
|
||||
}
|
||||
|
||||
private int getUsers(RRoom.Short room) {
|
||||
private int getUsers(ShortResponseRoom room) {
|
||||
var users = room.getDetail(RoomDetails.COUNT_USERS);
|
||||
if (users == null) return 0;
|
||||
try {
|
||||
return Integer.parseInt(room.details().getOrDefault(RoomDetails.COUNT_USERS, "0"));
|
||||
|
||||
return Integer.parseInt(users);
|
||||
} catch (NumberFormatException ex) {
|
||||
return 0;
|
||||
}
|
||||
@ -192,7 +192,7 @@ public class RoomList extends VerticalLayout implements RefreshableTable {
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
cachedRooms = roomRepository.all(node, RoomRepository.ALL_DETAILS);
|
||||
cachedRooms = roomRepository.allRooms(GetAllRooms.withAllDetails(node.getIdentifierObject()));
|
||||
applySearch(searchField.getValue());
|
||||
|
||||
int users = 0;
|
||||
|
||||
@ -9,25 +9,29 @@ import com.vaadin.flow.component.icon.Icon;
|
||||
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import ru.dragonestia.picker.api.model.room.IRoom;
|
||||
import ru.dragonestia.picker.api.model.user.IUser;
|
||||
import ru.dragonestia.picker.api.model.user.UserDetails;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.api.repository.request.user.GetAllUsersFromRoom;
|
||||
import ru.dragonestia.picker.api.repository.request.user.UnlinkUsersFromRoom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UserList extends VerticalLayout implements RefreshableTable {
|
||||
|
||||
private final RRoom room;
|
||||
private final IRoom room;
|
||||
private final UserRepository userRepository;
|
||||
private final Button buttonRemove;
|
||||
private final Grid<RUser> usersGrid;
|
||||
private final Grid<IUser> usersGrid;
|
||||
private final Span totalUsers = new Span();
|
||||
private final Span occupancy = new Span();
|
||||
private List<RUser> cachedUsers = new ArrayList<>();
|
||||
private List<IUser> cachedUsers = new ArrayList<>();
|
||||
|
||||
public UserList(RRoom room, UserRepository userRepository) {
|
||||
public UserList(IRoom room, UserRepository userRepository) {
|
||||
this.room = room;
|
||||
this.userRepository = userRepository;
|
||||
|
||||
@ -45,21 +49,25 @@ public class UserList extends VerticalLayout implements RefreshableTable {
|
||||
button.addClickListener(event -> {
|
||||
var users = usersGrid.getSelectedItems();
|
||||
if (users.isEmpty()) return;
|
||||
userRepository.unlinkFromRoom(room, users);
|
||||
userRepository.unlinkUsersFromRoom(UnlinkUsersFromRoom.builder()
|
||||
.setNodeId(room.getNodeIdentifierObject())
|
||||
.setRoomId(room.getIdentifierObject())
|
||||
.setUsers(users.stream().map(IUser::getIdentifierObject).collect(Collectors.toSet()))
|
||||
.build());
|
||||
refresh();
|
||||
});
|
||||
return button;
|
||||
}
|
||||
|
||||
private Grid<RUser> createUsersGrid() {
|
||||
var grid = new Grid<RUser>();
|
||||
private Grid<IUser> createUsersGrid() {
|
||||
var grid = new Grid<IUser>();
|
||||
|
||||
grid.addColumn(RUser::getId).setHeader("User Identifier").setSortable(true).setFooter(totalUsers);
|
||||
grid.addColumn(IUser::getIdentifier).setHeader("User Identifier").setSortable(true).setFooter(totalUsers);
|
||||
|
||||
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setTextAlign(ColumnTextAlign.CENTER)
|
||||
.setHeader("Linked with rooms").setComparator((user1, user2) -> {
|
||||
var r1 = Integer.parseInt(user1.getDetail(UserDetails.COUNT_ROOMS));
|
||||
var r2 = Integer.parseInt(user2.getDetail(UserDetails.COUNT_ROOMS));
|
||||
var r1 = Integer.parseInt(Objects.requireNonNull(user1.getDetail(UserDetails.COUNT_ROOMS)));
|
||||
var r2 = Integer.parseInt(Objects.requireNonNull(user2.getDetail(UserDetails.COUNT_ROOMS)));
|
||||
|
||||
return Integer.compare(r1, r2);
|
||||
}).setSortable(true).setFooter(occupancy);
|
||||
@ -73,11 +81,11 @@ public class UserList extends VerticalLayout implements RefreshableTable {
|
||||
return grid;
|
||||
}
|
||||
|
||||
private Button createManageButton(RUser user) {
|
||||
private Button createManageButton(IUser user) {
|
||||
var button = new Button("Details");
|
||||
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||
button.addClickListener(e -> {
|
||||
getUI().ifPresent(ui -> ui.navigate("/users/" + user.getId()));
|
||||
getUI().ifPresent(ui -> ui.navigate("/users/" + user.getIdentifier()));
|
||||
});
|
||||
return button;
|
||||
}
|
||||
@ -106,16 +114,17 @@ public class UserList extends VerticalLayout implements RefreshableTable {
|
||||
}
|
||||
|
||||
public static int getUsingPercentage(int slots, int usedSlots) {
|
||||
if (slots == RRoom.INFINITE_SLOTS) return -1;
|
||||
if (slots == IRoom.UNLIMITED_SLOTS) return -1;
|
||||
double percent = usedSlots / (double) slots * 100;
|
||||
return (int) percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
cachedUsers = userRepository.all(room, UserRepository.ALL_DETAILS);
|
||||
cachedUsers = userRepository.getAllUsersFormRoom(GetAllUsersFromRoom.withAllDetails(room.getNodeIdentifierObject(), room.getIdentifierObject()))
|
||||
.stream().map(user -> (IUser) user).toList();
|
||||
usersGrid.setItems(cachedUsers);
|
||||
totalUsers.setText("Total users: " + cachedUsers.size());
|
||||
occupancy.setText("Occupancy: %s".formatted(getUsingPercentage(room.getSlots(), cachedUsers.size()) + "%"));
|
||||
occupancy.setText("Occupancy: %s".formatted(getUsingPercentage(room.getMaxSlots(), cachedUsers.size()) + "%"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
package ru.dragonestia.picker.cp.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.cp.annotation.ServerURL;
|
||||
|
||||
@Configuration
|
||||
public class RoomPickerConfig {
|
||||
|
||||
@Value("${ROOMPICKER_HOST_URL:http://localhost:8080}")
|
||||
private String serverUrl;
|
||||
|
||||
@ServerURL
|
||||
@Bean
|
||||
String severUrl() {
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
@Bean
|
||||
RoomPickerClient roomPickerClient() {
|
||||
return new RoomPickerClient(serverUrl, "test", "test");
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package ru.dragonestia.picker.cp.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
@Configuration
|
||||
public class ServerConfig {
|
||||
|
||||
@Value("${ROOMPICKER_HOST_URL:http://localhost:8080/}")
|
||||
private String serverUrl;
|
||||
|
||||
@Bean
|
||||
URI serverUrl() {
|
||||
return URI.create(serverUrl);
|
||||
}
|
||||
}
|
||||
@ -9,18 +9,18 @@ import com.vaadin.flow.component.textfield.PasswordField;
|
||||
import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
|
||||
@Route("/login")
|
||||
public class LoginPage extends VerticalLayout {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final RoomPickerClient client;
|
||||
private final TextField fieldLogin;
|
||||
private final PasswordField fieldPassword;
|
||||
|
||||
@Autowired
|
||||
public LoginPage(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
public LoginPage(RoomPickerClient client) {
|
||||
this.client = client;
|
||||
|
||||
setAlignItems(Alignment.CENTER);
|
||||
|
||||
|
||||
@ -10,20 +10,20 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
import com.vaadin.flow.component.orderedlayout.Scroller;
|
||||
import com.vaadin.flow.component.sidenav.SideNav;
|
||||
import com.vaadin.flow.component.sidenav.SideNavItem;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import ru.dragonestia.picker.api.repository.RoomPickerRepository;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.repository.response.RoomPickerInfoResponse;
|
||||
|
||||
import java.net.URI;
|
||||
import ru.dragonestia.picker.cp.annotation.ServerURL;
|
||||
|
||||
public class MainLayout extends AppLayout {
|
||||
|
||||
private final RoomPickerInfoResponse info;
|
||||
private final RoomPickerClient client;
|
||||
private final RoomPickerInfoResponse serverInfo;
|
||||
private final String serverUrl;
|
||||
|
||||
public MainLayout(RoomPickerRepository roomPickerRepository, URI serverUrl) {
|
||||
info = roomPickerRepository.getInfo();
|
||||
this.serverUrl = serverUrl.toString();
|
||||
public MainLayout(RoomPickerClient client, @ServerURL String serverUrl) {
|
||||
this.client = client;
|
||||
this.serverInfo = client.getServerInfo();
|
||||
this.serverUrl = serverUrl;
|
||||
|
||||
var toggle = new DrawerToggle();
|
||||
var scroller = new Scroller(createSideNav());
|
||||
@ -37,7 +37,7 @@ public MainLayout(RoomPickerRepository roomPickerRepository, URI serverUrl) {
|
||||
layout.setAlignItems(FlexComponent.Alignment.END);
|
||||
layout.setPadding(true);
|
||||
layout.add(new Html("<h2><u>RoomPicker!</u></h2>"));
|
||||
layout.add(new Html("<sub>" + info.version() + "</sub>"));
|
||||
layout.add(new Html("<sub>" + serverInfo.version() + "</sub>"));
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
||||
@ -10,9 +10,8 @@ import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RNode;
|
||||
import ru.dragonestia.picker.api.repository.NodeRepository;
|
||||
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.model.node.INode;
|
||||
import ru.dragonestia.picker.cp.component.RoomList;
|
||||
import ru.dragonestia.picker.cp.component.NavPath;
|
||||
import ru.dragonestia.picker.cp.component.RegisterRoom;
|
||||
@ -24,28 +23,27 @@ import ru.dragonestia.picker.cp.util.RouteParamsExtractor;
|
||||
@Route(value = "/nodes/:nodeId", layout = MainLayout.class)
|
||||
public class NodeDetailsPage extends VerticalLayout implements BeforeEnterObserver {
|
||||
|
||||
private final NodeRepository nodeRepository;
|
||||
private final RoomRepository roomRepository;
|
||||
private final RoomPickerClient client;
|
||||
private final RouteParamsExtractor paramsExtractor;
|
||||
|
||||
private RNode node;
|
||||
private INode node;
|
||||
private RegisterRoom registerRoom;
|
||||
private RoomList roomList;
|
||||
|
||||
@Override
|
||||
public void beforeEnter(BeforeEnterEvent event) {
|
||||
node = paramsExtractor.extractNodeId(event);
|
||||
node = paramsExtractor.extractNode(event);
|
||||
|
||||
initComponents(node);
|
||||
}
|
||||
|
||||
private void initComponents(RNode node) {
|
||||
add(NavPath.toNode(node.getId()));
|
||||
private void initComponents(INode node) {
|
||||
add(NavPath.toNode(node.getIdentifier()));
|
||||
printNodeDetails(node);
|
||||
add(new Hr());
|
||||
add(registerRoom = new RegisterRoom(node, (room, persist) -> {
|
||||
add(registerRoom = new RegisterRoom(node, roomDefinition -> {
|
||||
try {
|
||||
roomRepository.register(room, persist);
|
||||
client.getRoomRepository().saveRoom(roomDefinition);
|
||||
return new RegisterRoom.Response(false, null);
|
||||
} catch (Error error) {
|
||||
return new RegisterRoom.Response(true, error.getMessage());
|
||||
@ -54,19 +52,15 @@ public class NodeDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
}
|
||||
}));
|
||||
add(new Hr());
|
||||
add(roomList = new RoomList(node, roomRepository));
|
||||
roomList.setRemoveMethod(room -> {
|
||||
roomRepository.remove(node, room);
|
||||
roomList.refresh();
|
||||
});
|
||||
add(roomList = new RoomList(node, client.getRoomRepository()));
|
||||
}
|
||||
|
||||
private void printNodeDetails(RNode node) {
|
||||
private void printNodeDetails(INode node) {
|
||||
add(new H2("Node details"));
|
||||
|
||||
var layout = new VerticalLayout();
|
||||
layout.add(new Html("<span>Identifier: <b>" + node.getId() + "</b></span>"));
|
||||
layout.add(new Html("<span>Mode: <b>" + node.getMode().getName() + "</b></span>"));
|
||||
layout.add(new Html("<span>Identifier: <b>" + node.getIdentifier() + "</b></span>"));
|
||||
layout.add(new Html("<span>Mode: <b>" + node.getPickingMethod().name() + "</b></span>"));
|
||||
|
||||
add(layout);
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import lombok.Getter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import ru.dragonestia.picker.api.exception.ApiException;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.repository.NodeRepository;
|
||||
import ru.dragonestia.picker.cp.component.NavPath;
|
||||
import ru.dragonestia.picker.cp.component.NodeList;
|
||||
@ -23,24 +24,20 @@ public class NodesPage extends VerticalLayout {
|
||||
private final RegisterNode registerNode;
|
||||
private final NodeList nodeList;
|
||||
|
||||
public NodesPage(@Autowired NodeRepository nodeRepository) {
|
||||
public NodesPage(@Autowired RoomPickerClient client) {
|
||||
super();
|
||||
this.nodeRepository = nodeRepository;
|
||||
this.nodeRepository = client.getNodeRepository();
|
||||
|
||||
add(NavPath.rootNodes());
|
||||
add(registerNode = createRegisterNodeElement());
|
||||
add(new Hr());
|
||||
add(nodeList = createNodeListElement());
|
||||
nodeList.setRemoveMethod(nodeIdentifier -> {
|
||||
nodeRepository.remove(nodeIdentifier);
|
||||
nodeList.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
protected RegisterNode createRegisterNodeElement() {
|
||||
return new RegisterNode((node, persist) -> {
|
||||
return new RegisterNode(nodeDefinition -> {
|
||||
try {
|
||||
nodeRepository.register(node, persist);
|
||||
nodeRepository.saveNode(nodeDefinition);
|
||||
return new RegisterNode.Response(false, "");
|
||||
} catch (ApiException ex) {
|
||||
return new RegisterNode.Response(true, ex.getMessage());
|
||||
|
||||
@ -14,12 +14,12 @@ 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.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.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.model.node.INode;
|
||||
import ru.dragonestia.picker.api.model.room.IRoom;
|
||||
import ru.dragonestia.picker.api.model.room.ResponseRoom;
|
||||
import ru.dragonestia.picker.api.model.user.IUser;
|
||||
import ru.dragonestia.picker.api.repository.request.user.LinkUsersWithRoom;
|
||||
import ru.dragonestia.picker.cp.component.AddUsers;
|
||||
import ru.dragonestia.picker.cp.component.NavPath;
|
||||
import ru.dragonestia.picker.cp.component.Notifications;
|
||||
@ -28,19 +28,18 @@ import ru.dragonestia.picker.cp.util.RouteParamsExtractor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@PageTitle("Room details")
|
||||
@Route(value = "/nodes/:nodeId/rooms/:roomId", layout = MainLayout.class)
|
||||
public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserver {
|
||||
|
||||
private final NodeRepository nodeRepository;
|
||||
private final RoomRepository roomRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final RoomPickerClient client;
|
||||
private final RouteParamsExtractor paramsExtractor;
|
||||
|
||||
private RNode node;
|
||||
private RRoom room;
|
||||
private INode node;
|
||||
private ResponseRoom room;
|
||||
private AddUsers addUsers;
|
||||
private UserList userList;
|
||||
private Button lockRoomButton;
|
||||
@ -48,28 +47,28 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
|
||||
@Override
|
||||
public void beforeEnter(BeforeEnterEvent event) {
|
||||
node = paramsExtractor.extractNodeId(event);
|
||||
room = paramsExtractor.extractRoomId(event, node);
|
||||
node = paramsExtractor.extractNode(event);
|
||||
room = (ResponseRoom) paramsExtractor.extractRoom(event, node);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
add(NavPath.toRoom(node.getId(), room.getId()));
|
||||
add(NavPath.toRoom(node.getIdentifier(), room.getIdentifier()));
|
||||
add(new H2("Room details"));
|
||||
printRoomDetails();
|
||||
add(new Hr());
|
||||
add(addUsers = new AddUsers(room, (users, ignoreLimitation) -> appendUsers(room, users, ignoreLimitation)));
|
||||
add(new Hr());
|
||||
add(new H2("Users"));
|
||||
add(userList = new UserList(room, userRepository));
|
||||
add(userList = new UserList(room, client.getUserRepository()));
|
||||
}
|
||||
|
||||
private void updateRoomInfo() {
|
||||
roomInfo.removeAll();
|
||||
roomInfo.add(new Html("<span>Node identifier: <b>" + room.getNodeId() + "</b></span>"));
|
||||
roomInfo.add(new Html("<span>Room identifier: <b>" + room.getId() + "</b></span>"));
|
||||
roomInfo.add(new Html("<span>Slots: <b>" + (room.isUnlimited()? "Unlimited" : room.getSlots()) + "</b></span>"));
|
||||
roomInfo.add(new Html("<span>Node identifier: <b>" + room.getNodeIdentifier() + "</b></span>"));
|
||||
roomInfo.add(new Html("<span>Room identifier: <b>" + room.getIdentifier() + "</b></span>"));
|
||||
roomInfo.add(new Html("<span>Slots: <b>" + (room.hasUnlimitedSlots()? "Unlimited" : room.getMaxSlots()) + "</b></span>"));
|
||||
roomInfo.add(new Html("<span>Locked: <b>" + (room.isLocked()? "Yes" : "No") + "</b></span>"));
|
||||
}
|
||||
|
||||
@ -100,7 +99,7 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
|
||||
private void changeBucketLockedState() {
|
||||
var newValue = !room.isLocked();
|
||||
roomRepository.lock(room, newValue);
|
||||
client.getRoomRepository().lockRoom(room.getPath(), newValue);
|
||||
|
||||
room.setLocked(newValue);
|
||||
setLockRoomButtonState();
|
||||
@ -109,12 +108,12 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
Notifications.success("Success");
|
||||
}
|
||||
|
||||
private void appendUsers(RRoom room, Collection<RUser> users, boolean ignoreLimitation) {
|
||||
private void appendUsers(IRoom room, Collection<IUser> users, boolean ignoreLimitation) {
|
||||
AtomicBoolean validationFail = new AtomicBoolean(false);
|
||||
|
||||
var newUsers = users.stream()
|
||||
.filter(user -> {
|
||||
if (user.getId().matches("^[aA-zZ\\d-.\\s:/@%?!~$)(+=_|;*]+$")) {
|
||||
if (user.getIdentifier().matches("^[aA-zZ\\d-.\\s:/@%?!~$)(+=_|;*]+$")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -122,7 +121,11 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
return false;
|
||||
}).toList();
|
||||
|
||||
userRepository.linkWithRoom(room, newUsers, ignoreLimitation);
|
||||
client.getUserRepository().linkUsersWithRoom(LinkUsersWithRoom.builder()
|
||||
.setRoomId(room.getIdentifierObject())
|
||||
.setUsers(users.stream().map(IUser::getIdentifierObject).collect(Collectors.toSet()))
|
||||
.setIgnoreSlotLimitation(ignoreLimitation)
|
||||
.build());
|
||||
userList.refresh();
|
||||
|
||||
if (validationFail.get()) {
|
||||
|
||||
@ -13,54 +13,55 @@ 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.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.model.room.RoomDetails;
|
||||
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RRoom;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.api.model.room.ShortResponseRoom;
|
||||
import ru.dragonestia.picker.api.model.user.IUser;
|
||||
import ru.dragonestia.picker.api.repository.request.user.FindRoomsLinkedWithUser;
|
||||
import ru.dragonestia.picker.cp.component.RefreshableTable;
|
||||
import ru.dragonestia.picker.cp.util.RouteParamsExtractor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@PageTitle("User details")
|
||||
@Route(value = "/users/:userId", layout = MainLayout.class)
|
||||
public class UserDetailsPage extends VerticalLayout implements BeforeEnterObserver, RefreshableTable {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final RoomPickerClient client;
|
||||
private final RouteParamsExtractor paramsExtractor;
|
||||
private RUser user;
|
||||
private Grid<RRoom.Short> gridRooms;
|
||||
private List<RRoom.Short> cachedRooms = new LinkedList<>();
|
||||
private IUser user;
|
||||
private Grid<ShortResponseRoom> gridRooms;
|
||||
private List<ShortResponseRoom> cachedRooms = new LinkedList<>();
|
||||
|
||||
@Override
|
||||
public void beforeEnter(BeforeEnterEvent event) {
|
||||
user = paramsExtractor.extractUserId(event);
|
||||
user = paramsExtractor.extractUser(event);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
add(new H2("User '%s'".formatted(user.getId())));
|
||||
add(new H2("User '%s'".formatted(user.getIdentifier())));
|
||||
add(new H3("Linked with rooms"));
|
||||
add(gridRooms = createGrid());
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
private Grid<RRoom.Short> createGrid() {
|
||||
var grid = new Grid<RRoom.Short>();
|
||||
private Grid<ShortResponseRoom> createGrid() {
|
||||
var grid = new Grid<ShortResponseRoom>();
|
||||
|
||||
grid.addColumn(RRoom.Short::id).setHeader("Room identifier").setSortable(true);
|
||||
grid.addColumn(ShortResponseRoom::getIdentifier).setHeader("Room identifier").setSortable(true);
|
||||
|
||||
grid.addColumn(RRoom.Short::nodeId).setHeader("Node identifier").setSortable(true);
|
||||
grid.addColumn(ShortResponseRoom::getNodeIdentifier).setHeader("Node identifier").setSortable(true);
|
||||
|
||||
grid.addColumn(room -> room.details().get(RoomDetails.COUNT_USERS)).setHeader("Users")
|
||||
grid.addColumn(room -> room.getDetail(RoomDetails.COUNT_USERS)).setHeader("Users")
|
||||
.setComparator((room1, room2) -> {
|
||||
var r1 = Integer.parseInt(room1.details().get(RoomDetails.COUNT_USERS));
|
||||
var r2 = Integer.parseInt(room2.details().get(RoomDetails.COUNT_USERS));
|
||||
var r1 = Integer.parseInt(Objects.requireNonNull(room1.getDetail(RoomDetails.COUNT_USERS)));
|
||||
var r2 = Integer.parseInt(Objects.requireNonNull(room2.getDetail(RoomDetails.COUNT_USERS)));
|
||||
|
||||
return Integer.compare(r1, r2);
|
||||
}).setSortable(true);
|
||||
@ -69,7 +70,7 @@ public class UserDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
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())));
|
||||
getUI().ifPresent(ui -> ui.navigate("/nodes/%s/rooms/%s".formatted(room.getNodeIdentifier(), room.getIdentifier())));
|
||||
});
|
||||
return button;
|
||||
}).setTextAlign(ColumnTextAlign.END).setFrozenToEnd(true).setHeader(createRefreshButton());
|
||||
@ -84,7 +85,8 @@ public class UserDetailsPage extends VerticalLayout implements BeforeEnterObserv
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
cachedRooms = userRepository.getLinkedRoomsWithUsers(user, RoomRepository.ALL_DETAILS);
|
||||
cachedRooms = client.getUserRepository()
|
||||
.findRoomsLinkedWithUser(FindRoomsLinkedWithUser.withAllDetails(user.getIdentifierObject()));
|
||||
gridRooms.setItems(cachedRooms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,13 +14,17 @@ import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.model.user.IUser;
|
||||
import ru.dragonestia.picker.api.model.user.UserDetails;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
import ru.dragonestia.picker.api.repository.response.type.RUser;
|
||||
import ru.dragonestia.picker.api.repository.request.user.SearchUsers;
|
||||
import ru.dragonestia.picker.api.repository.type.UserIdentifier;
|
||||
import ru.dragonestia.picker.cp.component.RefreshableTable;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@PageTitle("Search users")
|
||||
@Route(value = "/users", layout = MainLayout.class)
|
||||
@ -28,13 +32,13 @@ public class UserSearchPage extends VerticalLayout implements RefreshableTable {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final TextField fieldUsername;
|
||||
private final Grid<RUser> userGrid;
|
||||
private final Grid<IUser> userGrid;
|
||||
private final Span foundUsers;
|
||||
private List<RUser> cachedUsers = new LinkedList<>();
|
||||
private List<IUser> cachedUsers = new LinkedList<>();
|
||||
|
||||
@Autowired
|
||||
public UserSearchPage(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
public UserSearchPage(RoomPickerClient client) {
|
||||
this.userRepository = client.getUserRepository();
|
||||
|
||||
foundUsers = new Span();
|
||||
add(fieldUsername = createUsernameInputField());
|
||||
@ -60,15 +64,15 @@ public class UserSearchPage extends VerticalLayout implements RefreshableTable {
|
||||
return field;
|
||||
}
|
||||
|
||||
private Grid<RUser> createUserGrid() {
|
||||
var grid = new Grid<RUser>();
|
||||
private Grid<IUser> createUserGrid() {
|
||||
var grid = new Grid<IUser>();
|
||||
|
||||
grid.addColumn(RUser::getId).setHeader("Identifier").setSortable(true)
|
||||
grid.addColumn(IUser::getIdentifier).setHeader("Identifier").setSortable(true)
|
||||
.setFooter(foundUsers);
|
||||
|
||||
grid.addColumn(user -> user.getDetail(UserDetails.COUNT_ROOMS)).setComparator((user1, user2) -> {
|
||||
var r1 = Integer.parseInt(user1.getDetail(UserDetails.COUNT_ROOMS));
|
||||
var r2 = Integer.parseInt(user2.getDetail(UserDetails.COUNT_ROOMS));
|
||||
var r1 = Integer.parseInt(Objects.requireNonNull(user1.getDetail(UserDetails.COUNT_ROOMS)));
|
||||
var r2 = Integer.parseInt(Objects.requireNonNull(user2.getDetail(UserDetails.COUNT_ROOMS)));
|
||||
|
||||
return Integer.compare(r1, r2);
|
||||
}).setTextAlign(ColumnTextAlign.CENTER).setHeader("Linked with rooms");
|
||||
@ -77,7 +81,7 @@ public class UserSearchPage extends VerticalLayout implements RefreshableTable {
|
||||
var button = new Button("Details");
|
||||
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||
button.addClickListener(event -> {
|
||||
getUI().ifPresent(ui -> ui.navigate("/users/" + user.getId()));
|
||||
getUI().ifPresent(ui -> ui.navigate("/users/" + user.getIdentifier()));
|
||||
});
|
||||
return button;
|
||||
}).setTextAlign(ColumnTextAlign.END).setFrozenToEnd(true).setHeader(createRefreshButton());
|
||||
@ -87,7 +91,8 @@ public class UserSearchPage extends VerticalLayout implements RefreshableTable {
|
||||
}
|
||||
|
||||
private void search(String input) {
|
||||
userGrid.setItems(cachedUsers = userRepository.search(input, UserRepository.ALL_DETAILS));
|
||||
userGrid.setItems(cachedUsers = userRepository.searchUsers(SearchUsers.withAllDetails(UserIdentifier.of(input)))
|
||||
.stream().map(user -> (IUser) user).toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
package ru.dragonestia.picker.cp.repository.impl;
|
||||
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
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.model.node.NodeDetails;
|
||||
import ru.dragonestia.picker.api.repository.response.NodeDetailsResponse;
|
||||
import ru.dragonestia.picker.api.repository.response.NodeListResponse;
|
||||
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
|
||||
@SpringComponent
|
||||
public class NodeRepositoryImpl implements NodeRepository {
|
||||
|
||||
private final RestUtil rest;
|
||||
|
||||
@Override
|
||||
public void register(RNode node, boolean persist) throws InvalidNodeIdentifierException, NodeAlreadyExistException {
|
||||
rest.query("nodes", HttpMethod.POST, params -> {
|
||||
params.put("nodeId", node.getId());
|
||||
params.put("method", node.getMode().name());
|
||||
params.put("persist", Boolean.toString(persist));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
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<RNode> find(String nodeId) {
|
||||
try {
|
||||
var response = rest.query("nodes/" + nodeId, HttpMethod.GET, NodeDetailsResponse.class, params -> {});
|
||||
return Optional.of(response.node());
|
||||
} catch (NodeNotFoundException ex) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String nodeId) {
|
||||
rest.query("nodes/" + nodeId, HttpMethod.DELETE, params -> {});
|
||||
}
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
package ru.dragonestia.picker.cp.repository.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import ru.dragonestia.picker.api.exception.ExceptionFactory;
|
||||
import ru.dragonestia.picker.api.repository.response.ErrorResponse;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RestUtil {
|
||||
|
||||
private final URI serverUrl;
|
||||
private final Supplier<RestTemplate> restTemplateSupplier;
|
||||
|
||||
public void query(String uri, HttpMethod method) {
|
||||
query(uri, method, ParamsConsumer.NONE);
|
||||
}
|
||||
|
||||
public void query(String uri, HttpMethod method, ParamsConsumer paramsConsumer) {
|
||||
var params = new HashMap<String, String>();
|
||||
paramsConsumer.accept(params);
|
||||
|
||||
var template = restTemplateSupplier.get();
|
||||
try {
|
||||
template.exchange(buildPath(uri, params.keySet()), method, null, String.class, params);
|
||||
} catch (HttpClientErrorException ex) {
|
||||
throw ExceptionFactory.of(Objects.requireNonNull(ex.getResponseBodyAs(ErrorResponse.class)));
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T query(String uri, HttpMethod method, Class<T> clazz) {
|
||||
return query(uri, method, clazz, ParamsConsumer.NONE);
|
||||
}
|
||||
|
||||
public <T> T query(String uri, HttpMethod method, Class<T> clazz, ParamsConsumer paramsConsumer) {
|
||||
var params = new HashMap<String, String>();
|
||||
paramsConsumer.accept(params);
|
||||
|
||||
var template = restTemplateSupplier.get();
|
||||
try {
|
||||
return template.exchange(buildPath(uri, params.keySet()), method, null, clazz, params).getBody();
|
||||
} catch (HttpClientErrorException ex) {
|
||||
throw ExceptionFactory.of(Objects.requireNonNull(ex.getResponseBodyAs(ErrorResponse.class)));
|
||||
}
|
||||
}
|
||||
|
||||
private String buildPath(String uri, Collection<String> paramKeys) {
|
||||
var path = new StringBuilder(serverUrl.resolve(uri) + "?");
|
||||
int left = paramKeys.size();
|
||||
for (var key: paramKeys) {
|
||||
path.append(key);
|
||||
path.append("={");
|
||||
path.append(key);
|
||||
path.append("}");
|
||||
if (--left > 0) {
|
||||
path.append("&");
|
||||
}
|
||||
}
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
public interface ParamsConsumer extends Consumer<Map<String, String>> {
|
||||
|
||||
ParamsConsumer NONE = map -> {};
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package ru.dragonestia.picker.cp.repository.impl;
|
||||
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import ru.dragonestia.picker.api.repository.RoomPickerRepository;
|
||||
import ru.dragonestia.picker.api.repository.response.RoomPickerInfoResponse;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@SpringComponent
|
||||
public class RoomPickerRepositoryImpl implements RoomPickerRepository {
|
||||
|
||||
private final RestUtil rest;
|
||||
|
||||
@Override
|
||||
public RoomPickerInfoResponse getInfo() {
|
||||
return rest.query("/info", HttpMethod.GET, RoomPickerInfoResponse.class, params -> {});
|
||||
}
|
||||
}
|
||||
@ -1,73 +0,0 @@
|
||||
package ru.dragonestia.picker.cp.repository.impl;
|
||||
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.http.HttpMethod;
|
||||
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.room.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
|
||||
@SpringComponent
|
||||
public class RoomRepositoryImpl implements RoomRepository {
|
||||
|
||||
private final RestUtil rest;
|
||||
|
||||
@Override
|
||||
public void register(RRoom room, boolean persist) 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()));
|
||||
params.put("payload", room.getPayload());
|
||||
params.put("locked", Boolean.toString(room.isLocked()));
|
||||
params.put("persist", Boolean.toString(persist));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(RRoom room) throws NodeNotFoundException {
|
||||
rest.query("/nodes/" + room.getNodeId() + "/rooms/" + room.getId(), HttpMethod.DELETE, params -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(RNode node, RRoom.Short room) throws NodeNotFoundException {
|
||||
rest.query("/nodes/" + node.getId() + "/rooms/" + room.id(), HttpMethod.DELETE, params -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
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<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());
|
||||
} catch (RoomNotFoundException ex) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
package ru.dragonestia.picker.cp.repository.impl;
|
||||
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
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.RoomDetails;
|
||||
import ru.dragonestia.picker.api.model.user.UserDetails;
|
||||
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.response.RoomUserListResponse;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Log4j2
|
||||
@RequiredArgsConstructor
|
||||
@SpringComponent
|
||||
public class UserRepositoryImpl implements UserRepository {
|
||||
|
||||
private final RestUtil rest;
|
||||
|
||||
@Override
|
||||
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(RUser::getId).toList()));
|
||||
params.put("force", Boolean.toString(force));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
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(RUser::getId).toList()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
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 -> {
|
||||
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||
|
||||
params.put("requiredDetails", detailsStr);
|
||||
}).users();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RUser> search(String input, Set<UserDetails> details) {
|
||||
return rest.query("/users/search",
|
||||
HttpMethod.GET,
|
||||
SearchUserResponse.class,
|
||||
params -> {
|
||||
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||
|
||||
params.put("requiredDetails", detailsStr);
|
||||
params.put("input", input);
|
||||
}).users();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RUser find(String userId, Set<UserDetails> details) {
|
||||
return rest.query("/users/" + userId,
|
||||
HttpMethod.GET,
|
||||
UserDetailsResponse.class,
|
||||
params -> {
|
||||
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||
|
||||
params.put("requiredDetails", detailsStr);
|
||||
}).user();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RRoom.Short> getLinkedRoomsWithUsers(RUser user, Set<RoomDetails> details) {
|
||||
return rest.query("/users/" + user.getId() + "/rooms",
|
||||
HttpMethod.GET,
|
||||
LinkedRoomsWithUserResponse.class,
|
||||
params -> {
|
||||
var detailsStr = String.join(",", details.stream().map(Enum::toString).toList());
|
||||
|
||||
params.put("requiredDetails", detailsStr);
|
||||
}).rooms(); // TODO
|
||||
}
|
||||
}
|
||||
@ -5,33 +5,36 @@ 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;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.model.node.INode;
|
||||
import ru.dragonestia.picker.api.model.room.IRoom;
|
||||
import ru.dragonestia.picker.api.model.user.IUser;
|
||||
import ru.dragonestia.picker.api.repository.request.node.FindNodeById;
|
||||
import ru.dragonestia.picker.api.repository.request.room.FindRoomById;
|
||||
import ru.dragonestia.picker.api.repository.request.user.FindUserById;
|
||||
import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
|
||||
import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
|
||||
import ru.dragonestia.picker.api.repository.type.UserIdentifier;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RouteParamsExtractor {
|
||||
|
||||
private final NodeRepository nodeRepository;
|
||||
private final RoomRepository roomRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final RoomPickerClient client;
|
||||
|
||||
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 INode extractNode(BeforeEnterEvent e) throws NodeNotFoundException {
|
||||
var nodeId = NodeIdentifier.of(e.getRouteParameters().get("nodeId").orElseThrow(() -> new NodeNotFoundException("null")));
|
||||
return client.getNodeRepository().findNodeById(FindNodeById.justFind(nodeId)).orElseThrow(() -> new NodeNotFoundException(nodeId.getValue()));
|
||||
}
|
||||
|
||||
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));
|
||||
public IRoom extractRoom(BeforeEnterEvent e, INode node) throws RoomNotFoundException {
|
||||
var nodeId = node.getIdentifierObject();
|
||||
var roomId = RoomIdentifier.of(e.getRouteParameters().get("roomId").orElseThrow(() -> new NodeNotFoundException("null")));
|
||||
return client.getRoomRepository().find(FindRoomById.just(nodeId, roomId)).orElseThrow(() -> new NodeNotFoundException(roomId.getValue()));
|
||||
}
|
||||
|
||||
public RUser extractUserId(BeforeEnterEvent e) {
|
||||
var userId = e.getRouteParameters().get("userId").orElseThrow(RuntimeException::new);
|
||||
return userRepository.find(userId, UserRepository.ALL_DETAILS);
|
||||
public IUser extractUser(BeforeEnterEvent e) {
|
||||
var userId = UserIdentifier.of(e.getRouteParameters().get("userId").orElseThrow(RuntimeException::new));
|
||||
return client.getUserRepository().findUserById(FindUserById.withAllDetails(userId));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user