From 49461199cd1e9b5af2c2e686990bd0cd94626bb5 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 28 Aug 2025 10:18:50 +0200 Subject: [PATCH] implemented editor for times --- .../srsoftware/umbrella/core/model/Time.java | 17 +++++++-- frontend/src/Components/DateTimeEditor.svelte | 24 ------------ .../src/Components/TimeRecordEditor.svelte | 37 ++++++++++++++++++ frontend/src/routes/time/Index.svelte | 38 ++++++++----------- translations/src/main/resources/de.json | 1 + 5 files changed, 67 insertions(+), 50 deletions(-) delete mode 100644 frontend/src/Components/DateTimeEditor.svelte create mode 100644 frontend/src/Components/TimeRecordEditor.svelte 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 639d265..efaec7d 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 @@ -108,12 +108,21 @@ public class Time implements Mappable{ ); } + private LocalDateTime parse(String time){ + if (time.contains("T")) return LocalDateTime.parse(time); + return LocalDateTime.parse(time,DT); + } + public Time patch(JSONObject json) { if (json.has(SUBJECT) && json.get(SUBJECT) instanceof String s) subject = s; - if (json.has(DESCRIPTION) && json.get(DESCRIPTION) instanceof String d) description = d; - if (json.has(START_TIME) && json.get(START_TIME) instanceof String st) start = LocalDateTime.parse(st, DT); - if (json.has(END_TIME) && json.get(END_TIME) instanceof String e) end = LocalDateTime.parse(e,DT); - if (end != null && !start.isBefore(end)) throw UmbrellaException.invalidFieldException(END_TIME,"after start_time"); + if (json.has(DESCRIPTION)) { + var o = json.get(DESCRIPTION); + if (o instanceof JSONObject nested && nested.get(SOURCE) instanceof String src) o = src; + if (o instanceof String d) description = d; + } + if (json.has(START_TIME) && json.get(START_TIME) instanceof String st) start = parse(st); + if (json.has(END_TIME) && json.get(END_TIME) instanceof String e) end = parse(e); + if (end != null && end.isBefore(start)) throw UmbrellaException.invalidFieldException(END_TIME,"after start_time"); return this; } diff --git a/frontend/src/Components/DateTimeEditor.svelte b/frontend/src/Components/DateTimeEditor.svelte deleted file mode 100644 index b2d23af..0000000 --- a/frontend/src/Components/DateTimeEditor.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - - - -
- - - -
\ No newline at end of file diff --git a/frontend/src/Components/TimeRecordEditor.svelte b/frontend/src/Components/TimeRecordEditor.svelte new file mode 100644 index 0000000..8299f3a --- /dev/null +++ b/frontend/src/Components/TimeRecordEditor.svelte @@ -0,0 +1,37 @@ + + +{#if record} +
+
+ {t('edit_object',{object:t('record')})} + + + + + +
+
+{record.description.source} +{/if} diff --git a/frontend/src/routes/time/Index.svelte b/frontend/src/routes/time/Index.svelte index 1792739..a350633 100644 --- a/frontend/src/routes/time/Index.svelte +++ b/frontend/src/routes/time/Index.svelte @@ -4,14 +4,13 @@ import { api } from '../../urls.svelte.js'; import { t } from '../../translations.svelte.js'; - import DateTimeEditor from '../../Components/DateTimeEditor.svelte'; - import LineEditor from '../../Components/LineEditor.svelte'; - import MarkdownEditor from '../../Components/MarkdownEditor.svelte'; + import TimeEditor from '../../Components/TimeRecordEditor.svelte'; let error = $state(null); let router = useTinyRouter(); let times = $state(null); let detail = $state(null); + let sortedTimes = $derived.by(() => Object.values(times).sort((b, a) => a.start_time.localeCompare(b.start_time))); async function loadTimes(){ const url = api('time'); @@ -27,17 +26,20 @@ router.navigate(`task/${tid}/view`); } - async function update(tid,field,newVal){ - times[tid][field] = newVal; - detail = null; - const url = api(`time/${tid}`); + async function update(time){ + const url = api(`time/${time.id}`); + time.start_time = time.start_time.split(':').slice(0,2).join(':'); + time.end_time = time.end_time.split(':').slice(0,2).join(':'); const res = await fetch(url,{ credentials:'include', method:'PATCH', - body:JSON.stringify(times[tid]) + body:JSON.stringify(time) }); if (res.ok){ - times[tid] = await res.json(); + let json = await res.json(); + let id = json.id; + for (let key of Object.keys(json)) times[id][key] = json[key]; + detail = null; error = null; return true; } else { @@ -69,23 +71,15 @@ - {#each Object.entries(times) as [tid,time]} - {#if detail == tid} + {#each sortedTimes as time} + {#if detail == time.id} - -
- update(tid,'start_time',dateTime)} /> - … - update(tid,'end_time',dateTime)} /> -
- - - update(tid,'subject',subject)} /> - update(tid,'description',desc)} /> + + {:else} - {detail = tid}}> + {detail = time.id}}> {time.start_time}{#if time.end_time}…{time.end_time}{/if} diff --git a/translations/src/main/resources/de.json b/translations/src/main/resources/de.json index d5a65cd..eeb83f4 100644 --- a/translations/src/main/resources/de.json +++ b/translations/src/main/resources/de.json @@ -173,6 +173,7 @@ "project": "Projekt", "projects": "Projekte", + "record": "Eintrag", "repeat_new_password": "Wiederholung", "results": "Ergebnisse",