einfache Reservierung möglich
This commit is contained in:
10
pom.xml
10
pom.xml
@@ -79,6 +79,16 @@
|
|||||||
<artifactId>rest-assured</artifactId>
|
<artifactId>rest-assured</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.quarkus</groupId>
|
||||||
|
<artifactId>quarkus-test-security</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.quarkus</groupId>
|
||||||
|
<artifactId>quarkus-panache-mock</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.webjars</groupId>
|
<groupId>org.webjars</groupId>
|
||||||
<artifactId>bootstrap</artifactId>
|
<artifactId>bootstrap</artifactId>
|
||||||
|
|||||||
15
src/main/java/de/mbremer/extension/CommonExtensions.java
Normal file
15
src/main/java/de/mbremer/extension/CommonExtensions.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package de.mbremer.extension;
|
||||||
|
|
||||||
|
import io.quarkus.qute.TemplateExtension;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@TemplateExtension
|
||||||
|
public class CommonExtensions {
|
||||||
|
|
||||||
|
public static String formatCommon(LocalDate date) {
|
||||||
|
return date == null ? "" : date.atStartOfDay(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("EEEE, d.M.yyyy"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,31 @@
|
|||||||
package de.mbremer.kalender;
|
package de.mbremer.kalender;
|
||||||
|
|
||||||
|
import de.mbremer.secutity.User;
|
||||||
import io.quarkus.qute.Template;
|
import io.quarkus.qute.Template;
|
||||||
import io.quarkus.qute.TemplateInstance;
|
import io.quarkus.qute.TemplateInstance;
|
||||||
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
||||||
|
|
||||||
import javax.annotation.security.RolesAllowed;
|
import javax.annotation.security.RolesAllowed;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.ws.rs.GET;
|
import javax.persistence.NoResultException;
|
||||||
import javax.ws.rs.Path;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.*;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Path("/kalender")
|
@Path("/kalender")
|
||||||
@RolesAllowed({"USER", "ADMIN"})
|
@RolesAllowed({"USER", "ADMIN"})
|
||||||
public class KalenderResource {
|
public class KalenderResource {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Logger log;
|
||||||
|
@Inject
|
||||||
|
SecurityIdentity identity;
|
||||||
@Inject
|
@Inject
|
||||||
Template kalender;
|
Template kalender;
|
||||||
|
|
||||||
@@ -21,6 +33,54 @@ public class KalenderResource {
|
|||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.TEXT_HTML)
|
@Produces(MediaType.TEXT_HTML)
|
||||||
public TemplateInstance kalender() {
|
public TemplateInstance kalender() {
|
||||||
return kalender.instance();
|
User currentUser = User.find("username", identity.getPrincipal().getName()).singleResult();
|
||||||
|
LocalDate today = LocalDate.now();
|
||||||
|
|
||||||
|
LocalDate montag = today.minusDays(today.getDayOfWeek().getValue() - 1);
|
||||||
|
|
||||||
|
List<KalenderTag> week0 = getWeek(currentUser, montag);
|
||||||
|
List<KalenderTag> week1 = getWeek(currentUser, montag.plusDays(7));
|
||||||
|
List<KalenderTag> week2 = getWeek(currentUser, montag.plusDays(14));
|
||||||
|
|
||||||
|
return kalender
|
||||||
|
.data("today", today)
|
||||||
|
.data("week0", week0)
|
||||||
|
.data("week1", week1)
|
||||||
|
.data("week2", week2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<KalenderTag> getWeek(User currentUser, LocalDate start) {
|
||||||
|
return Stream.iterate(0, i -> i < 5, i -> ++i)
|
||||||
|
.map(d -> {
|
||||||
|
LocalDate day = start.plusDays(d);
|
||||||
|
KalenderTag tag = (KalenderTag) KalenderTag.find("day", day).singleResultOptional().orElse(new KalenderTag(day));
|
||||||
|
tag.setCurrentUserInOffice(currentUser.equals(tag.getInOffice()));
|
||||||
|
return tag;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Transactional
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Path("/inoffice/{day}")
|
||||||
|
public TemplateInstance update(@PathParam("day") String day, @MultipartForm KalenderTagForm kalenderForm) {
|
||||||
|
LocalDate dayParsed = LocalDate.parse(day);
|
||||||
|
|
||||||
|
User currentUser = User.find("username", identity.getPrincipal().getName()).singleResult();
|
||||||
|
try {
|
||||||
|
KalenderTag tag = KalenderTag.find("day", dayParsed).singleResult();
|
||||||
|
if (kalenderForm.isInOffice() && tag.getInOffice() == null) {
|
||||||
|
tag.setInOffice(currentUser);
|
||||||
|
} else if (!kalenderForm.isInOffice() && currentUser.equals(tag.getInOffice())) {
|
||||||
|
tag.setInOffice(null);
|
||||||
|
}
|
||||||
|
} catch (NoResultException e) {
|
||||||
|
KalenderTag tag = new KalenderTag(dayParsed);
|
||||||
|
tag.setInOffice(currentUser);
|
||||||
|
tag.persist();
|
||||||
|
}
|
||||||
|
|
||||||
|
return kalender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,27 @@ package de.mbremer.kalender;
|
|||||||
import de.mbremer.secutity.User;
|
import de.mbremer.secutity.User;
|
||||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.Transient;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Entity
|
||||||
public class KalenderTag extends PanacheEntity {
|
public class KalenderTag extends PanacheEntity {
|
||||||
|
|
||||||
private LocalDate date;
|
private LocalDate day;
|
||||||
@OneToMany
|
@OneToOne
|
||||||
private User inOffice;
|
private User inOffice;
|
||||||
|
@Transient
|
||||||
|
private boolean currentUserInOffice;
|
||||||
|
|
||||||
|
public KalenderTag(LocalDate day) {
|
||||||
|
this.day = day;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/main/java/de/mbremer/kalender/KalenderTagForm.java
Normal file
16
src/main/java/de/mbremer/kalender/KalenderTagForm.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package de.mbremer.kalender;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.providers.multipart.PartType;
|
||||||
|
|
||||||
|
import javax.ws.rs.FormParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
public class KalenderTagForm {
|
||||||
|
@FormParam("inoffice")
|
||||||
|
@PartType(MediaType.TEXT_PLAIN)
|
||||||
|
String inOffice;
|
||||||
|
|
||||||
|
boolean isInOffice() {
|
||||||
|
return "on".equals(inOffice);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,6 @@ quarkus.flyway.migrate-at-start=true
|
|||||||
|
|
||||||
# Security
|
# Security
|
||||||
quarkus.http.auth.form.enabled=true
|
quarkus.http.auth.form.enabled=true
|
||||||
quarkus.http.auth.session.encryption-key=zHId14V+uiyxmbzhEPCyi7VvbaI80UeEO5yu0H/hVLs=
|
#quarkus.http.auth.session.encryption-key=zHId14V+uiyxmbzhEPCyi7VvbaI80UeEO5yu0H/hVLs=
|
||||||
# 24h
|
# 24h
|
||||||
quarkus.http.auth.form.timeout=86400
|
quarkus.http.auth.form.timeout=86400
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ create table users (
|
|||||||
|
|
||||||
create table kalendertag (
|
create table kalendertag (
|
||||||
id bigint not null primary key,
|
id bigint not null primary key,
|
||||||
date date not null unique,
|
day date not null unique,
|
||||||
inoffice_id bigint not null references users
|
inoffice_id bigint references users
|
||||||
);
|
);
|
||||||
@@ -3,10 +3,93 @@
|
|||||||
{#contents}
|
{#contents}
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
aktuelle Woche<br>
|
Heute ist {today.formatCommon}
|
||||||
nächste Woche<br>
|
</div>
|
||||||
übernächste Woche<br>
|
<div class="mt-2">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="col-2">Ich will ins Büro</th>
|
||||||
|
<th scope="col" class="col-3">Datum</th>
|
||||||
|
<th scope="col">Im Büro</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#for day in week0}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<form action="/kalender/inoffice/{day.day}" method="POST" name="kalenderForm" enctype="multipart/form-data">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" name="inoffice" onchange="this.form.submit()"
|
||||||
|
{#if day.isCurrentUserInOffice}checked{/if} >
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{day.day.formatCommon}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if day.inOffice}{day.inOffice.username}{/if}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
{/for}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/contents}
|
<div class="mt-2">
|
||||||
{/include}
|
<table class="table table-striped table-bordered">
|
||||||
|
<tbody>
|
||||||
|
{#for day in week1}
|
||||||
|
<tr>
|
||||||
|
<td class="col-2">
|
||||||
|
<form action="/kalender/inoffice/{day.day}" method="POST" name="kalenderForm" enctype="multipart/form-data">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" name="inoffice" onchange="this.form.submit()"
|
||||||
|
{#if day.isCurrentUserInOffice}checked{/if} >
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td class="col-3">
|
||||||
|
{day.day.formatCommon}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if day.inOffice}{day.inOffice.username}{/if}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{/for}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<tbody>
|
||||||
|
{#for day in week2}
|
||||||
|
<tr>
|
||||||
|
<td class="col-2">
|
||||||
|
<form action="/kalender/inoffice/{day.day}" method="POST" name="kalenderForm" enctype="multipart/form-data">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" name="inoffice" onchange="this.form.submit()"
|
||||||
|
{#if day.isCurrentUserInOffice}checked{/if} >
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td class="col-3">
|
||||||
|
{day.day.formatCommon}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if day.inOffice}{day.inOffice.username}{/if}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{/for}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/contents}
|
||||||
|
{/include}
|
||||||
15
src/test/java/de/mbremer/extension/CommonExtensionsTest.java
Normal file
15
src/test/java/de/mbremer/extension/CommonExtensionsTest.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package de.mbremer.extension;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class CommonExtensionsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatCommon() {
|
||||||
|
assertEquals("Sonntag, 4.7.2021", CommonExtensions.formatCommon(LocalDate.of(2021, 7, 4)));
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/test/java/de/mbremer/kalender/KalenderResourceTest.java
Normal file
44
src/test/java/de/mbremer/kalender/KalenderResourceTest.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package de.mbremer.kalender;
|
||||||
|
|
||||||
|
import de.mbremer.secutity.User;
|
||||||
|
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
|
||||||
|
import io.quarkus.hibernate.orm.panache.PanacheQuery;
|
||||||
|
import io.quarkus.panache.mock.PanacheMock;
|
||||||
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
|
import io.quarkus.test.junit.mockito.InjectMock;
|
||||||
|
import io.quarkus.test.security.TestSecurity;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@QuarkusTest
|
||||||
|
class KalenderResourceTest {
|
||||||
|
|
||||||
|
@InjectMock
|
||||||
|
SecurityIdentity identity;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestSecurity(authorizationEnabled = false)
|
||||||
|
void testKalender() {
|
||||||
|
PanacheMock.mock(User.class);
|
||||||
|
Principal principal = Mockito.mock(Principal.class);
|
||||||
|
PanacheQuery<PanacheEntityBase> query = Mockito.mock(PanacheQuery.class);
|
||||||
|
|
||||||
|
when(principal.getName()).thenReturn("admin");
|
||||||
|
when(identity.getPrincipal()).thenReturn(principal);
|
||||||
|
when(query.singleResult()).thenReturn(new User());
|
||||||
|
when(User.find("username", "admin")).thenReturn(query);
|
||||||
|
|
||||||
|
given()
|
||||||
|
.when().get("/kalender")
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.body(containsString("Heute ist"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user