From 45c2f3978fb24d6f00ecee788c4785c0f5c161f1 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Mon, 1 Sep 2025 23:31:46 +0200 Subject: [PATCH] implemented joining of times --- .../srsoftware/umbrella/core/model/Time.java | 15 ++++ frontend/src/routes/time/Index.svelte | 23 ++++++ .../srsoftware/umbrella/time/Constants.java | 2 +- .../srsoftware/umbrella/time/TimeModule.java | 70 +++++++++++++++---- translations/src/main/resources/de.json | 3 +- web/src/main/resources/web/css/default.css | 13 ++++ 6 files changed, 111 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Time.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Time.java index 72470c2..10ee9e5 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Time.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Time.java @@ -68,10 +68,20 @@ public class Time implements Mappable{ return description; } + public Time description(String newVal) { + description = newVal; + return this; + } + public Long end(){ return end; } + public Time end(Long newVal) { + end = newVal; + return this; + } + public long id(){ return id; } @@ -143,6 +153,11 @@ public class Time implements Mappable{ return subject; } + public Time subject(String newValue) { + subject = newValue; + return this; + } + public Collection taskIds(){ return taskIds; } diff --git a/frontend/src/routes/time/Index.svelte b/frontend/src/routes/time/Index.svelte index da5af63..9dad526 100644 --- a/frontend/src/routes/time/Index.svelte +++ b/frontend/src/routes/time/Index.svelte @@ -59,6 +59,26 @@ return result; } + async function joinTimes(evt, id1, id2){ + evt.preventDefault(); + evt.stopPropagation(); + const url = api('time/join'); + const res = await fetch(url,{ + credentials : 'include', + method : 'POST', + body : `${id1}+${id2}` + }); + if (res.ok){ + error = null; + let json = await res.json(); + delete times[id1]; + delete times[id2]; + times[json.id] = json; + } else { + error = await res.text(); + } + return false; + } async function loadTimes(){ const url = api('time'); @@ -189,6 +209,9 @@ {:else} toggleSelect(time.id)}> {time.start}{#if time.end_time}{time.start.startsWith(time.end_date)?time.end.substring(11):time.end}{/if} + {#if line>0 && Math.abs(sortedTimes[line-1].start_time - time.end_time)<100} + + {/if} {detail = time.id}}> {#if time.duration} diff --git a/time/src/main/java/de/srsoftware/umbrella/time/Constants.java b/time/src/main/java/de/srsoftware/umbrella/time/Constants.java index 3e7ad64..f0324b1 100644 --- a/time/src/main/java/de/srsoftware/umbrella/time/Constants.java +++ b/time/src/main/java/de/srsoftware/umbrella/time/Constants.java @@ -7,7 +7,7 @@ public class Constants { public static final String CHILDREN = "children"; public static final String CONFIG_DATABASE = "umbrella.modules.time.database"; - + public static final String JOIN = "join"; public static final String PROJECTS = "projects"; public static final String TABLE_TASK_TIMES = "task_times"; public static final String TABLE_TIMES = "times"; diff --git a/time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java b/time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java index 63723bf..910151a 100644 --- a/time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java +++ b/time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java @@ -6,6 +6,7 @@ import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Paths.*; import static de.srsoftware.umbrella.core.Util.mapValues; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; +import static de.srsoftware.umbrella.core.model.Time.State.Open; import static de.srsoftware.umbrella.core.model.Time.State.Started; import static de.srsoftware.umbrella.time.Constants.*; import static java.util.stream.Collectors.toSet; @@ -76,18 +77,6 @@ public class TimeModule extends BaseHandler implements TimeService { } } - private boolean getStoppedTask(UmbrellaUser user, long timeId, HttpExchange ex) throws IOException { - long now; - try { - now = Long.parseLong(body(ex)); - } catch (NumberFormatException e) { - throw unprocessable("request body does not contain a timestamp!"); - } - var time = timeDb.load(timeId); - timeDb.save(time.stop(now)); - return sendContent(ex,time); - } - @Override public boolean doPatch(Path path, HttpExchange ex) throws IOException { addCors(ex); @@ -114,6 +103,7 @@ public class TimeModule extends BaseHandler implements TimeService { if (user.isEmpty()) return unauthorized(ex); var head = path.pop(); return switch (head) { + case JOIN -> joinTimes(ex,user.get()); case LIST -> listTimes(ex,user.get()); case TRACK_TASK -> trackTask(user.get(),path,ex); default -> { @@ -129,13 +119,67 @@ public class TimeModule extends BaseHandler implements TimeService { } } - private Optional